簡體   English   中英

使用 JOIN 對 3 個表進行 SQL COUNT

[英]SQL COUNT on 3 tables with JOIN

我在數據庫中有 4 個表。 倉庫包含客戶擁有的箱子,箱子里有文件。 有一個Client表、一個Warehouse表、一個Boxes表和一個Files表。

所以Client表有WarehouseID作為外鍵, Boxes表有ClientID作為外鍵, Files表有BoxID作為外鍵。 我想統計每個客戶在我的查詢中擁有的箱子和文件的數量,以及進出倉庫的箱子數量。 BoxesFiles表上的Status字段確定箱子和文件是在倉庫內還是在倉庫外。 我在盒子上運行以下查詢並且數字是正確的:

SELECT
    [c].[ClientID],
    [c].[Name] AS [ClientName],
    [w].[Name] AS [WarehouseName],
    COUNT(DISTINCT [b].[BoxID]) AS [BoxCount],
    SUM(CASE WHEN [b].[Status] = @IN THEN 1 ELSE 0 END)) AS [BoxesIn],
    SUM(CASE WHEN [b].[Status] = @OUT THEN 1 ELSE 0 END) AS [BoxesOut],
    SUM(CASE WHEN [b].[DestructionDate] <= GETDATE() THEN 1 ELSE 0 END) AS [BoxesForDestruction],
FROM [Clients] AS [c] INNER JOIN [Boxes] AS [b]
  ON [c].[ClientID] = [b].[ClientID]
INNER JOIN [Warehouses] AS [w]
  ON [c].WarehouseID = [w].[WarehouseID]
WHERE [c].[ClientID] = @ClientID
GROUP BY
  [c].[ClientID],
  [c].[Name],
  [w].[Name]

這會產生以下輸出:

ClientID | ClientName | WarehouseName | BoxCount | BoxesIn | BoxesOut | BoxesForDestruction
1        | ACME Corp. | FooFactory    | 22744    | 22699   | 45       | 7888 

計數的輸出是正確的。 當我將Files表添加到INNER JOIN ,數字會膨脹。 這是 SQL:

SELECT
    [c].[ClientID],
    [c].[Name] AS [ClientName],
    [w].[Name] AS [WarehouseName],
    COUNT(DISTINCT [b].[BoxID]) AS [BoxCount],
    COUNT(DISTINCT [f].[FileID]) AS [FileCount], -- *NEW*
    SUM(CASE WHEN [b].[Status] = @IN THEN 1 ELSE 0 END)) AS [BoxesIn],
    SUM(CASE WHEN [b].[Status] = @OUT THEN 1 ELSE 0 END) AS [BoxesOut],
    SUM(CASE WHEN [b].[DestructionDate] <= GETDATE() THEN 1 ELSE 0 END) AS [BoxesForDestruction],
FROM [Clients] AS [c] INNER JOIN [Boxes] AS [b]
  ON [c].[ClientID] = [b].[ClientID]
INNER JOIN [Warehouses] AS [w]
  ON [c].[WarehouseID] = [w].[WarehouseID]
INNER JOIN [Files] AS [f]      -- *NEW*
  ON [b].[BoxID] = [f].[BoxID] -- *NEW*
WHERE [c].[ClientID] = @ClientID
GROUP BY
  [c].[ClientID],
  [c].[Name],
  [w].[Name]

這給了我下面的計數輸出(我省略了前 3 列,因為它們不相關):

BoxCount | FilesCount | BoxesIn | BoxesOut | BoxesForDestruction 
19151    | 411961     | 411381  | 580      | 144615       

FilesCount是正確的,但其他數字是關閉的。 我知道為什么會發生這種情況,但我不確定如何解決。 由於框和文件上的連接返回了多行,因此會創建額外的行。 執行SUM ,額外的行會增加計數。 由於倉庫只有一行,因此該連接不會影響計數。 如何修改我的查詢以獲得正確數量的進出倉庫的文件和箱子?

一個join重復左手表的每一行中右手表的每一行。 如果您組合多個連接,某些行將被重復計算。 一種解決方案是將計數移動到子查詢。 例如:

select  *
from    table1 t1
join    (
        select  table1_id
        ,       count(*)
        from    table2
        group by
                table1_id
        ) t2
on      t2.table1_id = t1.id
join    (
        select  table1_id
        ,       count(*)
        from    table3
        group by
                table1_id
        ) t3
on      t3.table1_id = t1.id

正如 Andomar 所提到的,除了 Count(*) 之外,我還包括了“as myColumnOne”和“myColumnTwo”,因為它在 SQL Server 2018 上是必需的:

 select  *
from    table1 t1
join    (
        select  table1_id
        ,       count(*) as myColumnOne
        from    table2
        group by
                table1_id
        ) t2
on      t2.table1_id = t1.id
join    (
        select  table1_id
        ,       count(*) as myColumnTwo
        from    table3
        group by
                table1_id
        ) t3
on      t3.table1_id = t1.id

暫無
暫無

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

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