簡體   English   中英

Sql 服務器等效於 COUNTIF 聚合 function

[英]Sql Server equivalent of a COUNTIF aggregate function

我正在使用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 function 稱為COUNTIF ,但這里的想法是確定 MyColumn 的值為“1”的所有行的百分比。

關於如何在 MS SQL 2005 環境中正確實現這一點的任何想法?

您可以將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

我通常會按照 Josh 的建議去做,但集思廣益並測試了一個我覺得想分享的稍微有點做作的替代方案。

您可以利用 COUNT(ColumnName) 不計算 NULL 的事實,並使用以下內容:

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

NULLIF - 如果傳入的兩個值相同,則返回 NULL。

優點:表達您對 COUNT 行的意圖,而不是使用 SUM() 表示法。 缺點:不清楚它是如何工作的(“魔法”通常很糟糕)。

我會使用這種語法。 它與 Josh 和 Chris 的建議相同,但優點是它符合 ANSI 並且不依賴於特定的數據庫供應商。

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

怎么樣

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

CASE短:)

有效,因為COUNT()不計算 null 值,並且IF / CASE在不滿足條件且沒有ELSE時返回 null 。

我認為這比使用SUM()更好。

加上喬希的回答,

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

對我來說效果很好(在 SQL Server 2012 中),無需將“計數”更改為“總和”,並且相同的邏輯可移植到其他“條件聚合”。 例如,基於條件求和:

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

以此目的。 或者與它非常相似的東西,我完全不知道。

當然,供應商更願意堅持使用他們的專有解決方案。

現在是 2022 年,最新的 SQL 服務器仍然沒有COUNTIF (以及正則表達式。):這是我使用的:

-- Count if MyColumn = 42
SELECT SUM(IIF(MyColumn = 42, 1, 0))
FROM MyTable

IIFCASE WHEN MyColumn = 42 THEN 1 ELSE 0 END的快捷方式。

為什么不這樣?

SELECT count(1)
FROM AD_CurrentView
WHERE myColumn=1

在我的案例中,我必須使用 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

當然,您需要根據您的顯示要求格式化結果。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM