postgresql-sql-`true` 값 개수


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

위의 표에서 다음을 수행하면

select count(*), count(myCol);

나는 얻다 6, 5

5null 항목을 계산하지 않기 때문에 얻 습니다.

참 값의 수도 계산하는 방법 (예제에서 3)

(이것은 단순화이며 실제로 count 함수 내에서 훨씬 더 복잡한 표현식을 사용하고 있습니다)

요약 편집 : 쿼리에 일반 개수 (*)도 포함하고 싶으므로 where 절을 사용할 수 없습니다.


't'는 True를 의미하고 'f'는 False를 의미합니까? 또는 SELECT COUNT (DISTINCT myCol)과 같은 것을 찾고 있습니까?
Shamit Verma 2011

두 번째 예제를 살펴보면 WHERE myCol = true원하는 경우 거기에 넣을 수 있으며 첫 번째를 제거 *,하면 번호가 반환됩니다.
vol7ron 2011 년

@Shamit 예 t 사실을 의미하고, 거짓을위한 스탠드 f를, 내가 질문을 업데이 트했습니다
EoghanM

질문 / 쿼리를 단순화하지 않을 수도 있습니다. 요구 사항은 더 나은 성능 가능성을 제한하고 사람들은 정당한 이유없이 비효율적 인 답변으로 응답하고 있습니다.
vol7ron 2011 년

1
@ vol7ron 내 변호에서 이해할 수있는 질문을하기 위해서는 약간의 단순화가 필요하지만, 예, 처음 게시했을 때 지나치게 단순화했습니다.
EoghanM 2011 년

답변:


133
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>

이것은 좋은 해킹이며 나로부터 정답을 얻습니다. 누군가가 더 짧은 해결책을 제시하지 않는 한 받아들일까요?
EoghanM 2011 년

2
또한 count (.. THEN true else null) 대신 sum (.. THEN 1 ELSE 0)을 한 이유는 무엇입니까?
EoghanM 2011 년

5
아니요 ... 어떤 값이 count () count () 될지 확실하지 않았고 합계가 트릭을 수행한다는 것을 알았습니다. 그러나 조심하십시오 : 두 번째 생각에 나는 sum ()이 null 값만이 null을 반환 할 것이라고 생각하므로 COALESCE (sum (...), 0)이어야합니다. 즉, count ()가 더 좋습니다.
Daniel

1
@EoghanM, 캐스트와 관련된 짧은 답변을 참조하십시오.
Dwayne Towell 2014 년

1
ELSE null동일한 결과를 얻기 위해 실제로 생략 할 수 있습니다.
200_success

91

부울을 정수와 합계로 캐스팅합니다.

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

당신은 6,3.


3
Plus1 : 멋진 해킹! 이것은 아마도 내 솔루션보다 더 빠를 것입니다.
Daniel

1
이것은 가장 좋고 가장 짧은 솔루션이며 다른 많은 프로그래밍 환경 및 소프트웨어에서도 동일합니다. 더 많은 찬성 투표를해야합니다

3
'cast to int and count'는 분명히 가장 간결하지만 이것이 최선의 방법은 아닙니다. 많은 환경에서 false / true에 대해 0/1 표현을 사용하는 반면 많은 환경에서는 -1을 포함하여 0 / non-zero를 사용하기 때문에 이것을지지하지 않습니다. 나는 그것이 "해킹"이라는 것에 동의하고 캐스트는 "해킹"이 아닐 때 충분히 엉망이된다. 반대표를 던지지는 않지만 다시지지하지 않습니다.
Andrew Wolfe

81

PostgreSQL 9.4부터는 참 값을 계산하는 매우 간결한 쿼리를 허용 하는 FILTER절이 있습니다.

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

위의 쿼리는 간단한 WHERE 절로 충분하다는 점에서 나쁜 예이며 구문을 보여주기위한 것입니다. FILTER 절이 빛나는 곳은 다른 집계와 결합하기 쉽다는 것입니다.

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
"일반적으로"가 잘못 보입니다. AFAICS nullif([boolean expression], true)false[부울 표현식]이 거짓이면 null반환하고 참이면 거짓 값을 계산합니다. 나는 당신이 원하는 것 같아요 nullif([boolean expression], false).
rjmunro

네, "일반적인"경우는 반대가되어야합니다. 결정된. 감사.
wrobell

1
수다. 그 수정은 정말 혼란 스럽습니다. AFAICS, 이제 true 또는 null 값을 계산합니다. 나는 당신이 항상 가지고 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);

이것은 확실히 내 것보다 더 좋은 해결책입니다. :)
Daniel

매우 통찰력있는 답변입니다.
lucasarruda

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
;

이것은 내가 본 것 중 가장 간단한 솔루션입니다 ^ _ ^
JiaHao Xu

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 경우 myColexpression이 부울이며, 당신이 체크 교체 할 수 있습니다where (myCol)
ypercubeᵀᴹ

죄송합니다. 예제를 지나치게 단순화했습니다. 전체 행 수와 실제 값 수를 나타내는 총 수를 반환하고 싶기 때문에 where 절을 사용할 수 없습니다.
EoghanM 2011 년

7

부울 필드를 정수로 변환하고 합계를 수행하십시오. 이것은 postgresql에서 작동합니다.

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

도움이 되었기를 바랍니다.


다른 솔루션보다 빠르지도 정확하지도 않습니다. 부울이 더 직관적이기 때문에 int를 사용할 때 Oracle에서 왔습니다.
Daniel

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

Windowing 기능을 사용하는 방법은 다음과 같습니다.

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

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

이 솔루션을 적용하는 더 복잡한 예제에 대해 여러 행을 반환 할 수 없습니다.
EoghanM 2011 년

예,하지만 WHERE myCol = true. 두 번째 예제는 더 빠르기 때문이 아니라 많은 사용자가 익숙하지 않거나 잘 모르는 Postgres의 창 기능에 대한 교육적인 부분으로 더 많이 제공했습니다.
vol7ron 2011 년

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

bool의 3 가지 가능한 상태 (false, true, 0)를 3 개의 행으로 그룹화합니다. 특히 day와 같은 다른 열과 함께 그룹화 할 때 편리합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.