postgresql - sql - `true` मानों की गिनती


97
myCol
------
 true
 true
 true
 false
 false
 null

उपरोक्त तालिका में, यदि मैं:

select count(*), count(myCol);

मुझे मिला 6, 5

मुझे मिलता है 5क्योंकि यह अशक्त प्रविष्टि की गणना नहीं करता है।

मैं सही मानों की संख्या (उदाहरण में 3) कैसे गिनूं?

(यह एक सरलीकरण है और मैं वास्तव में गिनती समारोह के भीतर बहुत अधिक जटिल अभिव्यक्ति का उपयोग कर रहा हूं)

सारांश संपादित करें: मैं क्वेरी में एक सादा गिनती (*) भी शामिल करना चाहता हूं, इसलिए एक क्लॉज का उपयोग नहीं कर सकता


क्या झूठी के लिए 't' ट्रू एनफ 'f' के लिए खड़ा है? या आप सेलेक्ट काउंट (DISTINCT myCol) जैसी किसी चीज की तलाश कर रहे हैं।
शमिता वर्मा

मेरे दूसरे उदाहरण पर एक नज़र डालें, WHERE myCol = trueयदि आप चाहें तो आप *,इसे वहां फेंक सकते हैं और यदि आप पहले हटाते हैं तो यह नंबर वापस कर देगा।
Vol7ron

@ शमाइट्स हाँ टी के लिए खड़ा है, और एफ झूठ के लिए खड़ा है, मैं सवाल अद्यतन किया है
EoghanM

आप अपने प्रश्न / प्रश्न को सरल नहीं बना सकते हैं ... आपकी आवश्यकताओं ने बेहतर प्रदर्शन संभावनाओं को प्रतिबंधित किया है और लोग अयोग्य उत्तर दे रहे हैं, जो बिना किसी अच्छे कारण के टकरा रहे हैं।
Vol7ron

1
@ मेरे बचाव में Vol7ron को एक सुस्पष्ट प्रश्न पूछने के लिए कुछ सरलीकरण करना होगा, लेकिन हां, जब मैंने मूल रूप से पोस्ट किया था, तो मैंने इसकी पुष्टि की थी।
EoghanM

जवाबों:


132
SELECT COALESCE(sum(CASE WHEN myCol THEN 1 ELSE 0 END),0) FROM <table name>

या, जैसा कि आपने खुद के लिए पाया:

SELECT count(CASE WHEN myCol THEN 1 END) FROM <table name>

यह एक अच्छा हैक है और मुझे इसका सही जवाब मिलता है। मैं इसे तब तक स्वीकार करूंगा जब तक कोई छोटा समाधान लेकर नहीं आता?
ईओघनम

2
इसके अलावा, किसी भी कारण से आपने गणना के बजाय (.. 1 ईएलएसई 0) का योग किया (.. सच है और अशक्त)?
इघनम

5
नहीं ... यह सिर्फ इतना है कि मुझे यकीन नहीं था कि कौन से मूल्यों की गणना होगी () गिनती ... और मुझे पता था कि राशि ने चाल चली। लेकिन सावधान रहें: दूसरे विचार पर मेरा मानना ​​है कि केवल शून्य मानों पर योग () शून्य हो जाएगा, इसलिए यह आपके लिए COALESCE (राशि (...), 0) होना चाहिए, या, दूसरे शब्दों में, गिनती () बेहतर है,
डैनियल

1
@ EoghanM, कास्ट से जुड़े छोटे उत्तर देखें।
ड्वेन टॉवल

1
आप वास्तव ELSE nullमें एक ही परिणाम प्राप्त करने के लिए चूक सकते हैं ।
200_सफल

91

बूलियन को एक पूर्णांक और योग में जमा करें।

SELECT count(*),sum(myCol::int);

आपको मिलता है 6,3


3
प्लस 1: अच्छा हैक! यह शायद मेरे समाधान से भी तेज है।
डैनियल

1
यह सबसे अच्छा और सबसे छोटा समाधान है (और कई अन्य प्रोग्रामिंग वातावरण और सॉफ्टवेयर में तुल्यता है)। अधिक मतदान होना चाहिए

3
'इंट टू कास्ट एंड काउंट' स्पष्ट रूप से सबसे संक्षिप्त है, लेकिन यह इसे सर्वश्रेष्ठ नहीं बनाता है। मैं इसका समर्थन नहीं करूंगा, क्योंकि कई वातावरण झूठे / सच के लिए 0/1 प्रतिनिधित्व का उपयोग करते हैं, कई -1 सहित / 0-गैर-शून्य का उपयोग करते हैं। मैं मानता हूं कि यह "हैक" है, और जब वे "हैक" नहीं होते हैं, तो कास्ट पर्याप्त रूप से पासा होते हैं। हार नहीं मानेंगे, लेकिन फिर से समर्थन नहीं करेंगे।
एंड्रयू वोल्फ

79

PostgreSQL 9.4 के बाद से वहाँ FILTERक्लॉज है , जो सच्चे मूल्यों को गिनने के लिए बहुत संक्षिप्त क्वेरी की अनुमति देता है:

select count(*) filter (where myCol)
from tbl;

उपरोक्त क्वेरी एक बुरा उदाहरण है कि एक साधारण WHERE क्लॉज पर्याप्त होगा, और केवल सिंटैक्स प्रदर्शित करने के लिए है। जहां फिल्टर क्लॉज चमकता है, यह अन्य समुच्चय के साथ संयोजन करना आसान है:

select count(*), -- all
       count(myCol), -- non null
       count(*) filter (where myCol) -- true
from tbl;

एक स्तंभ पर समुच्चय के लिए खंड विशेष रूप से उपयोगी है, जो किसी अन्य स्तंभ को विधेय के रूप में उपयोग करता है, जबकि एक ही क्वेरी में अलग-अलग फ़िल्टर किए गए समुच्चय लाने की अनुमति होती है:

select count(*),
       sum(otherCol) filter (where myCol)
from tbl;

2
यह PG> 9.4 के लिए सबसे अच्छा जवाब है और अविश्वसनीय रूप से तेज़ है
जुआन रिकार्डो

47

शायद, सबसे अच्छा तरीका nullif फ़ंक्शन का उपयोग करना है।

सामान्य रूप में

select
    count(nullif(myCol = false, true)),  -- count true values
    count(nullif(myCol = true, true)),   -- count false values
    count(myCol);

या संक्षेप में

select
    count(nullif(myCol, true)),  -- count false values
    count(nullif(myCol, false)), -- count true values
    count(myCol);

http://www.postgresql.org/docs/9.0/static/functions-conditional.html


2
आपका "सामान्य रूप से" गलत लगता है: वायुसेना, nullif([boolean expression], true)वापस आ जाएगी falseयदि [बूलियन अभिव्यक्ति] झूठी है, और nullयदि यह सच है, तो आप झूठे मूल्यों की गिनती करेंगे। मुझे लगता है कि आप चाहते हैं nullif([boolean expression], false)
rjmunro

हां, "सामान्य" मामला दूसरे तरीके से होना चाहिए। तय की। धन्यवाद।
बजे

1
युक। यह फिक्स वास्तव में भ्रामक है। AFAICS, अब यह सही या अशक्त मूल्यों की गणना करेगा। मुझे लगता है कि इसे फिर से लिखना ताकि आपको हमेशा nullif([boolean expression], false)पढ़ने में आसानी हो। इसके बाद आप बूलियन एक्सप्रेशन पार्ट को अलग-अलग कर सकते हैं, जो कुछ भी आप चाहते हैं, इस मामले myCol = trueमें सच्चे मूल्यों myCol = falseको गिनने के लिए , या झूठे मूल्यों name='john'को गिनने के लिए , या जॉन आदि जैसे लोगों को गिनने के लिए
rjmunro

19

सबसे छोटा और सबसे हल्का (बिना कास्टिंग) समाधान सूत्र का उपयोग करना होगा:

SELECT COUNT(myCol OR NULL) FROM myTable;

इसे स्वयं आज़माएं:

SELECT COUNT(x < 7 OR NULL)
   FROM GENERATE_SERIES(0,10) t(x);

से समान परिणाम देता है

SELECT SUM(CASE WHEN x < 7 THEN 1 ELSE 0 END)
   FROM GENERATE_SERIES(0,10) t(x);

यह निश्चित रूप से मेरा एक अच्छा समाधान है :)
डैनियल

बहुत ही व्यावहारिक जवाब।
लुकासरदुदा

7

MySQL में, आप यह भी कर सकते हैं:

SELECT count(*) AS total
     , sum(myCol) AS countTrue --yes, you can add TRUEs as TRUE=1 and FALSE=0 !!
FROM yourTable
;

मुझे लगता है कि Postgres में, यह काम करता है:

SELECT count(*) AS total
     , sum(myCol::int) AS countTrue --convert Boolean to Integer
FROM yourTable
;

या बेहतर (:: बचने के लिए और मानक SQL सिंटैक्स का उपयोग करें):

SELECT count(*) AS total
     , sum(CAST(myCol AS int)) AS countTrue --convert Boolean to Integer
FROM yourTable
;

यह सबसे सरल उपाय है जिसे मैंने कभी देखा है _ _ ^
जियाओ जू

7
select f1,
       CASE WHEN f1 = 't' THEN COUNT(*) 
            WHEN f1 = 'f' THEN COUNT(*) 
            END AS counts,
       (SELECT COUNT(*) FROM mytable) AS total_counts
from mytable
group by f1

या शायद यह

SELECT SUM(CASE WHEN f1 = 't' THEN 1 END) AS t,
       SUM(CASE WHEN f1 = 'f' THEN 1 END) AS f,
       SUM(CASE WHEN f1 NOT IN ('t','f') OR f1 IS NULL THEN 1 END) AS others,
       SUM(CASE WHEN f1 IS NOT NULL OR f1 IS NULL THEN 1 ELSE 0 END) AS total_count
FROM mytable;

+1 यदि myColअभिव्यक्ति एक बूलियन है, तो आप चेक को बदल सकते हैंwhere (myCol)
ypercube

क्षमा करें, मैंने अपने उदाहरण की देखरेख की: मैं एक क्लॉज का उपयोग नहीं कर सकता क्योंकि मैं कुल पंक्तियों की कुल संख्या का प्रतिनिधित्व करने के साथ-साथ सच्चे मूल्यों की एक गिनती भी वापस करना चाहता हूं।
ईओघनम

7

बस बूलियन फ़ील्ड को पूर्णांक में बदलें और योग करें। यह postgresql पर काम करेगा:

select sum(myCol::int) from <table name>

उम्मीद है की वो मदद करदे!


यह अन्य समाधानों की तुलना में न तो अधिक तेज है और न ही अधिक सटीक है। मेरा मानना ​​है कि आप Oracle से आते हैं जब बूलियन का उपयोग करना आपके लिए अधिक सहज है।
डैनियल

4
SELECT count(*)         -- or count(myCol)
FROM   <table name>     -- replace <table name> with your table
WHERE  myCol = true;

यहाँ घुमावदार कार्य के साथ एक तरीका है:

SELECT DISTINCT *, count(*) over(partition by myCol)
FROM   <table name>;

-- Outputs:
-- --------------
-- myCol | count
-- ------+-------
--  f    |  2
--  t    |  3
--       |  1

क्षमा करें, मैं इस समाधान के लिए लागू होने वाले अधिक जटिल उदाहरण के लिए कई पंक्तियों को वापस नहीं कर सकता।
ईओघनम

हां, लेकिन आप इसे केवल जोड़कर आगे प्रतिबंधित कर सकते हैं WHERE myCol = true। मैंने दूसरा उदाहरण प्रदान किया क्योंकि यह किसी भी तेज़ नहीं है, लेकिन एक शैक्षिक टुकड़े के रूप में पोस्टग्रेज के विंडोिंग कार्यों के लिए अधिक है, जिनके बारे में बहुत से उपयोगकर्ता सहज नहीं हैं, या जिनके बारे में नहीं जानते हैं।
Vol7ron

0
select count(myCol)
from mytable
group by myCol
;

तीन पंक्तियों में बूल (झूठ, सच, 0) के 3 संभावित राज्यों को समूहित करेंगे, विशेष रूप से तब उपयोगी होगा जब एक और कॉलम के साथ एक दिन में समूह बनाना

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.