Sql Server эквивалент агрегатной функции COUNTIF - PullRequest
147 голосов
/ 24 февраля 2009

Я создаю запрос с предложением 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, но идея здесь в том, чтобы определить процент всех строк, имеющих значение '1' для MyColumn.

Есть мысли о том, как правильно реализовать это в среде MS SQL 2005?

Ответы [ 9 ]

300 голосов
/ 24 февраля 2009

Вы можете использовать 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
46 голосов
/ 24 февраля 2009

Я обычно делаю то, что рекомендовал Джош, но провёл мозговой штурм и протестировал слегка ненормальную альтернативу, которой я хотел поделиться.

Вы можете воспользоваться тем, что COUNT (ColumnName) не считает NULL, и использовать что-то вроде этого:

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

NULLIF - возвращает NULL, если два переданных значения совпадают.

Преимущество: Выражает ваше намерение СЧИТАТЬ строки вместо записи SUM (). Недостаток: не так ясно, как это работает («магия», как правило, плохо).

18 голосов
/ 04 марта 2010

Я бы использовал этот синтаксис. Он выполняет те же функции, что и предложения Джоша и Криса, но с преимуществом он соответствует стандарту ANSI и не привязан к конкретному поставщику баз данных.

select count(case when myColumn = 1 then 1 else null end)
from   AD_CurrentView
1 голос
/ 29 октября 2015

Добавление к ответу Джоша,

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

Работал хорошо для меня (в SQL Server 2012), не меняя «count» на «sum», и та же логика переносима на другие «условные агрегаты». Например, суммирование на основе условия:

SELECT SUM(CASE WHEN myColumn=1 THEN AD_CurrentView.NumberColumn ELSE 0 END)
FROM AD_CurrentView
0 голосов
/ 10 декабря 2018
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
0 голосов
/ 27 ноября 2017

Мне пришлось использовать COUNTIF () в моем случае как часть моих столбцов SELECT И чтобы имитировать% от числа раз, когда каждый элемент появлялся в моих результатах.

Так что я использовал это ...

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

Конечно, вам необходимо отформатировать результат в соответствии с вашими требованиями к отображению.

0 голосов
/ 25 июля 2017

Как насчет

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

Короче CASE:)

Работает, потому что COUNT() не считает нулевые значения, а IF / CASE возвращает ноль, если условие не выполнено и ELSE.

нет.

Я думаю, что это лучше, чем использовать SUM().

0 голосов
/ 30 октября 2014

Почему бы не так?

SELECT count(1)
FROM AD_CurrentView
WHERE myColumn=1
0 голосов
/ 05 сентября 2014

Не для конкретного продукта, но стандарт SQL обеспечивает

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

для этой цели. Или что-то, что очень похоже на это, я не знаю, с шапки.

И, конечно, поставщики предпочтут придерживаться своих фирменных решений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...