簡體   English   中英

Count()在SQL中沒有按預期工作

[英]Count() not working as expected in SQL

同事為我准備了一個表格,我需要映射數據,表格包含兩個字段,OP_ID和BillType。 理論上,兩者之間應該存在一對一的對應關系:每個Op_ID應該只有一種賬單類型。

然而,當我開始使用它時,我注意到有不同BillTypes的重復OP_ID。 例如:

OP_Id               BillType 
007a000v9GWkAAM BillReady 
007a000v9GWkAAM RateReady

首先,我構建了一個查詢,將數據分組為ID和BillTypes的唯一組合:

SELECT OP_ID, BillType
FROM MappingTable
GROUP BY OP_ID, BillType

很簡單。 該集應該並且確實包括上述兩個記錄。 然后,我圍繞此包裝另一個查詢來計算聚合數據集中的OP_Ids。 從理論上講,任何具有多個BillType的OP_ID都應該出現兩次,因此它應該返回一個> 1的計數。對嗎?

SELECT OP_ID, BillType, Count(OP_ID)
FROM 
    (
    SELECT OP_ID, BillType
    FROM MappingTable
    GROUP BY OP_ID, BillType
    ) Base
GROUP BY  OP_ID, BillType
HAVING Count(OP_ID) > 1

但是這個查詢什么都不返回。 更令人費解的是:當我刪除HAVING子句並將查詢限制為僅提取上述OP_ID時,因為我已經知道它是一個騙局,我得到的是:

OP_ID          BillType  CountOfOP_IDs
007a000v9GWkAAM BillReady   1
007a000v9GWkAAM RateReady   1

所以OP_ID 007a000v9GWkAAM顯然有兩條記錄,但SQL只計算一條!

這看起來很簡單,我確信我只是缺少一些關於COUNT()如何工作的基本知識。 作為參考,我正在研究SQL Server 2014,兩列都是nvarchar。 我還確認SQL將兩個記錄中的OP_ID評估為相同。 任何人都知道為什么會這樣嗎?

Count計算已分組為一行的行數。 只需從外部組刪除帳單類型。

另請參閱count distinct選項。 這可能會更容易。

該聲明

SELECT OP_ID, BillType
FROM MappingTable
GROUP BY OP_ID, BillType

是很長的路要走

SELECT DISTINCT OP_ID, BillType
FROM MappingTable

當您現在具有OP_IDBillType不同組合時,在這兩個字段上添加新的GROUP BY將不執行任何操作。

SELECT ...
FROM ( SELECT DISTINCT OP_ID, BillType
       FROM MappingTable
     ) Base
GROUP BY  OP_ID, BillType
HAVING Count(OP_ID) > 1

新的“組”將包含來自內部SELECT的1行,因此COUNT將始終為1,這意味着Count(OP_ID) > 1始終為false,並且您將不會返回任何內容。


也許你的意思是找到OP_Id值與多個BillType值。 如果是這樣,您應該BillType建議GROUP BY 刪除BillType

如果您對此感興趣(通常在研究時通常很好),您可以通過檢索第一個和最后一個BillType值來獲得結果中這些BillType值的兩個示例

SELECT OP_ID, COUNT(*), MIN(BillType), MAX(BillType)
FROM ( SELECT DISTINCT OP_ID, BillType
       FROM MappingTable
     ) Base
GROUP BY OP_ID
HAVING COUNT(*) > 1

您可以使用COUNT(DISTINCT ...)縮短整個語句,也可以按@DonKirkby的建議

SELECT OP_ID, COUNT(DISTINCT BillType), MIN(BillType), MAX(BillType)
FROM MappingTable
GROUP BY OP_ID
HAVING COUNT(DISTINCT BillType) > 1

你的方法很有意義。 我的猜測是OP_ID值略有不同 - 可能是由於編碼問題或角色相似。

這很容易找到。 這個查詢返回什么?

select mt.*
from mappingtable
where op_id = '007a000v9GWkAAM';

順便提一下,您可以將查詢簡化為:

SELECT OP_ID
FROM MappingTable
GROUP BY OP_ID
HAVING MIN(BillType) <> MAX(BillType);

如果要查看BillType值,請將GROUP_CONCAT(BillType)添加到SELECT

編輯:

以上都是正確的,但您的查詢不起作用,因為外部查詢按OP_IDBILL_TYPE分組。 試試這個版本:

SELECT OP_ID, Count(OP_ID)
FROM (SELECT OP_ID, BillType
      FROM MappingTable
      GROUP BY OP_ID, BillType
      ) Base
GROUP BY OP_ID
HAVING Count(OP_ID) > 1;

你沒有返回任何行,因為你要對相同的鍵進行兩次分組。 子查詢刪除重復項,因此外部的計數始終為1。

SELECT * 
FROM MappingTable 
WHERE OP_ID in (SELECT OP_ID 
                FROM (SELECT OP_ID, count(*) ct
                      FROM MappingTable
                      GROUP BY OP_ID)
                WHERE ct > 1)

BOTH列沒有(至少在您的示例中)重復,只是OP_ID的意外重復。

暫無
暫無

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

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