COUNTIF 집계 함수에 해당하는 SQL Server


164

GROUP BY특정 조건 (예 : 특정 열 값이 1 인 레코드 만 계산)을 기반으로 레코드를 계산하는 기능이 필요한 절을 사용 하여 쿼리를 작성하고 있습니다.

SELECT  UID, 
        COUNT(UID) AS TotalRecords, 
        SUM(ContractDollars) AS ContractDollars,
        (COUNTIF(MyColumn, 1) / COUNT(UID) * 100) -- Get the average of all records that are 1
FROM    dbo.AD_CurrentView
GROUP BY UID
HAVING  SUM(ContractDollars) >= 500000

COUNTIF()라는 네이티브 SQL 기능이 없기 때문에 선은 분명히 실패COUNTIF , 그러나 여기에서 아이디어는 MyColumn의 값 '1'이 모든 행의 비율을 결정하는 것입니다.

MS SQL 2005 환경에서이를 올바르게 구현하는 방법에 대한 생각이 있습니까?

답변:


339

다음 과 같이 명령문 과 결합 된 SUM( COUNT! 아님)을 사용할 수 있습니다 CASE.

SELECT SUM(CASE WHEN myColumn=1 THEN 1 ELSE 0 END)
FROM AD_CurrentView

참고 : 내 테스트 NULL에서는 환경에 따라 다를 수 있지만 문제가되지 않았습니다. 다음과 같은 널을 처리 할 수 ​​있습니다.

SELECT SUM(CASE WHEN ISNULL(myColumn,0)=1 THEN 1 ELSE 0 END)
FROM AD_CurrentView

3
(나는 영업 이익은 MS SQL에 대해 물었을 알고,하지만 같은 일을하고 SQLite는 사용자를위한 단지 작은 코멘트) SQLite는 더이 ISNULL대신 당신이 할 수있는, CASE WHEN myColumn IS NULL또는 사용 ifnull( stackoverflow.com/a/799406/1861346 )
매트

54

나는 보통 조쉬가 추천 한 일을했지만 공유하고 싶은 약간의 대안을 브레인 스토밍하고 테스트했습니다.

COUNT (ColumnName)이 NULL을 계산하지 않는다는 사실을 이용하고 다음과 같은 것을 사용할 수 있습니다.

SELECT COUNT(NULLIF(0, myColumn))
FROM AD_CurrentView

NULLIF-전달 된 두 값이 동일한 경우 NULL을 반환합니다.

장점 : SUM () 표기법 대신 COUNT 개의 행으로 의도를 표현합니다. 단점 : 작동 방식이 명확하지 않습니다 ( "매직"은 일반적으로 나쁩니다).


2
이 솔루션은 그룹에 null 만 포함 된 경우 0이 아닌 1이됩니다.
KimvdLinde

오래된 게시물이지만 도움이되었습니다. 마법을 확장하고 ISNULL다음과 같이 추가하여 "only nulls"문제를 해결했습니다 SELECT COUNT(NULLIF(0, ISNULL(myColumn, 0))). 잠깐, 그건 못 생겼어 ...
pcdev

1
NULLIFNOT 함수가 있다면 완벽 할 것입니다
qwertzguy

21

이 구문을 사용합니다. Josh 및 Chris의 제안과 동일하지만 ANSI를 준수하며 특정 데이터베이스 공급 업체와 관련이 없습니다.

select count(case when myColumn = 1 then 1 else null end)
from   AD_CurrentView

2
Chris의 답변은 Stndard SQL과 호환됩니다 (힌트 : NULLIF표준 SQL-92 포함). Josh의 답변은로 대체 isnull하여 쉽게 표준 SQL로 변환 할 수 있습니다 COALESCE.
onedaywhen

Chris가 보여준 "행을 세는"아이디어를 얻었 기 때문에이 답변이 가장 좋습니다. 그러나 비교 연산자를 사용할 수 있기 때문에 더 확장 가능합니다. 뿐만 아니라 =. "응답 수 계산 == 2"에 사용하고 있습니다.
Kristen Hammack

3

조쉬의 대답에 덧붙여서

SELECT COUNT(CASE WHEN myColumn=1 THEN AD_CurrentView.PrimaryKeyColumn ELSE NULL END)
FROM AD_CurrentView

'count'를 'sum'으로 변경하지 않고 SQL Server 2012에서 잘 작동했으며 동일한 논리를 다른 '조건부 집계'로 이식 할 수 있습니다. 예 : 조건에 따라 합산 :

SELECT SUM(CASE WHEN myColumn=1 THEN AD_CurrentView.NumberColumn ELSE 0 END)
FROM AD_CurrentView

2

어때요?

SELECT id, COUNT(IF status=42 THEN 1 ENDIF) AS cnt
FROM table
GROUP BY table

CASE:) 보다 짧음

때문에 작품 COUNT()null 값을 계산하지 않고,하지 않습니다 IF/ CASE는 null를 조건이 충족되지 않을 때 더있다ELSE 합니다.

나는 그것을 사용하는 것보다 낫다고 생각합니다 SUM().


1

제품 별로는 아니지만 SQL 표준은

SELECT COUNT() FILTER WHERE <condition-1>, COUNT() FILTER WHERE <condition-2>, ... FROM ...

이 목적을 위해. 또는 그것을 닮은 것, 나는 모자의 꼭대기를 모른다.

물론 공급 업체는 독점 솔루션을 선호합니다.


1
나는 이것에 대해 들어 본 적이 없기 때문에 그것을 찾았습니다. modern-sql.com/feature/filter 에 따르면 실제로이FILTER 절을 제공하는 유일한 주요 DBMS 는 PostgreSQL이지만 CASE모두에 의해 에뮬레이트됩니다 .
Kristen Hammack

1

왜 이러지 않습니까?

SELECT count(1)
FROM AD_CurrentView
WHERE myColumn=1

1
그는 그 수보다 더 많은 것이 필요하기 때문입니다. 그는 그룹의 일부에 대한 행 수를 얻은 다음 전체 그룹의 집계를 얻으려고합니다. 어디로도 할 수 없습니다.
Kristen Hammack

1

내 경우에는 SELECT 열의 일부로 COUNTIF ()를 사용하고 각 항목이 결과에 나타나는 횟수의 %를 모방해야했습니다.

그래서 나는 이것을 사용했다 ...

SELECT COL1, COL2, ... ETC
       (1 / SELECT a.vcount 
            FROM (SELECT vm2.visit_id, count(*) AS vcount 
                  FROM dbo.visitmanifests AS vm2 
                  WHERE vm2.inactive = 0 AND vm2.visit_id = vm.Visit_ID 
                  GROUP BY vm2.visit_id) AS a)) AS [No of Visits],
       COL xyz
FROM etc etc

물론 디스플레이 요구 사항에 따라 결과를 포맷해야합니다.


-2
SELECT COALESCE(IF(myColumn = 1,COUNT(DISTINCT NumberColumn),NULL),0) column1,
COALESCE(CASE WHEN myColumn = 1 THEN COUNT(DISTINCT NumberColumn) ELSE NULL END,0) AS column2
FROM AD_CurrentView
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.