SQL Server эквивалент статистической функции COUNTIF
Я строю запрос с 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
The COUNTIF() строка явно не работает, так как нет собственной функции SQL с именем COUNTIF, но идея здесь состоит в том, чтобы определить процент всех строк, которые имеют значение '1' для MyColumn.
любые мысли о том, как правильно реализовать это в MS SQL 2005 и окружающая среда?
8 ответов:
вы могли бы использовать
SUM(неCOUNT!) в сочетании сCASEзаявления, вроде этого:SELECT SUM(CASE WHEN myColumn=1 THEN 1 ELSE 0 END) FROM AD_CurrentViewПримечание: В моем собственном тесте
NULLs не были проблемой, хотя это может зависеть от окружающей среды. Вы можете обрабатывать нули, такие как:SELECT SUM(CASE WHEN ISNULL(myColumn,0)=1 THEN 1 ELSE 0 END) FROM AD_CurrentView
Я обычно делаю то, что рекомендовал Джош, но мозговой штурм и тестирование немного Хоки альтернативы, что я чувствовал, как поделиться.
вы можете воспользоваться тем, что COUNT (ColumnName) не считает null, и использовать что-то вроде этого:
SELECT COUNT(NULLIF(0, myColumn)) FROM AD_CurrentViewNULLIF-возвращает NULL, если два переданных значения одинаковы.
преимущество: выражает ваше намерение подсчитывать строки вместо того, чтобы иметь обозначение SUM (). Недостаток: не так ясно, как это работает ("магия", как правило, плохо).
Я бы использовал этот синтаксис. Он работает так же, как предложения Джоша и Криса, но с преимуществом он является ANSI compliant и не привязан к конкретному поставщику базы данных.
select count(case when myColumn = 1 then 1 else null end) from AD_CurrentView
добавляя к ответу Джоша,
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
не зависит от продукта, но стандарт SQL предоставляет
SELECT COUNT() FILTER WHERE <condition-1>, COUNT() FILTER WHERE <condition-2>, ... FROM ...для этой цели. Или что-то очень похожее на него, я не знаю, с верхней части моей шляпы.
и, конечно, поставщики предпочтут придерживаться своих собственных решений.
как о
SELECT id, COUNT(IF status=42 THEN 1 ENDIF) AS cnt FROM table GROUP BY tableкороче
CASE:)работает, потому что
COUNT()не считает нулевые значения, иIF/CASEвозвращает null, когда условие не выполняется и нетELSE.Я думаю, что это лучше, чем с помощью
SUM().
мне пришлось использовать 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конечно, вам нужно будет отформатировать результат в соответствии с вашими требованиями к дисплею.
Comments