簡體   English   中英

帶有COUNTs的SQL和帶有跨UNION GROUP BY的SUM

[英]SQL with COUNTs and SUMs with cross-UNION GROUP BY

SQL大師需要,這是殺死我的神經元。 我有這樣的數據庫結構(簡化):

DESC documents;
    id          INT PK
    bill_id     INT FK
    dtype       INT -- 1=receipts, 0=invoices
    total       DECIMAL

DESC bills;
    id          INT PK
    waiter_id   INT FK

DESC waiters;
    id          INT PK
    name        VARCHAR
    surname     VARCHAR

相當不言自明,但我需要計算所有收據(documents.dtype = 1)和發票(documents.dtype = 0)的總數,並按服務員分組。 我做了兩個SELECT:

SELECT
        B.waiter_id,
        WA.name, 
        WA.surname, 
        COUNT(D.id) AS Receipts, 
        SUM(D.total) AS TotReceipts
FROM    
    documents D
    JOIN bills B ON (B.id = D.bill_id)
    JOIN waiters WA ON (WA.id = B.waiter_id)
WHERE 
    D.dtype = 1          
GROUP BY 
    waiter_id;

好吧,我明白了:

1, 'Mario',   'Rossi',   6, 485.20
2, 'Luigino', 'Bianchi', 1, 456.00

做了第二個SELECT,只是將documents.dtype更改為0:

SELECT
        B.waiter_id,
        WA.name, 
        WA.surname, 
        COUNT(D.id) AS Invoices, 
        SUM(D.total) AS TotInvoices
FROM    
    documents D
    JOIN bills B ON (B.id = D.bill_id)
    JOIN waiters WA ON (WA.id = B.waiter_id)
WHERE 
    D.dtype = 0 
GROUP BY 
    waiter_id;

現在我得到:

1, 'Mario', 'Rossi', 1, 38.00

現在我可以聯合兩個SELECTS

SELECT
        B.waiter_id,
        WA.name, 
        WA.surname, 
        COUNT(D.id) AS Receipts, 
        SUM(D.total) AS TotReceipts
FROM    
    documents D
    JOIN bills B ON (B.id = D.bill_id)
    JOIN waiters WA ON (WA.id = B.waiter_id)
WHERE 
    D.dtype = 1      
GROUP BY 
    waiter_id
UNION SELECT
        B.waiter_id,
        WA.name, 
        WA.surname, 
        COUNT(D.id) AS Invoices, 
        SUM(D.total) AS TotInvoices
FROM    
    documents D
    JOIN bills B ON (B.id = D.bill_id)
    JOIN waiters WA ON (WA.id = B.waiter_id)
WHERE 
    D.dtype = 0 
GROUP BY 
    waiter_id;

我得到:

1, 'Mario',   'Rossi',   6, 485.20
2, 'Luigino', 'Bianchi', 1, 456.00
1, 'Mario',   'Rossi',   1, 38.00

嗯,正確,但我需要由服務員交叉聯合分組的行! 那是我想要服務員馬里奧的一行:

wid wname       wsurname    receipts    totreceipts     invoices        totinvoices
1,  'Mario',    'Rossi',    6,          485.20          1               38.0
2,  'Luigino',  'Bianchi',  1,          456.00          0               0.0

那會很棒,但我還想再增加兩列來總結這些數字:

wid wname       wsurname    receipts    totreceipts     invoices        totinvoices     docs    totdocs
1,  'Mario',    'Rossi',    6,          485.20          1               38.0            7       523.20
2,  'Luigino',  'Bianchi',  1,          456.00          0               0.0             1       456.00

這將超級超酷。

您可以將conditon從where子句移動到case語句,如:

SELECT
        B.waiter_id,
        WA.name, 
        WA.surname, 
        SUM(case when d.dtype = 1 then 1 end) AS Receipts, 
        SUM(case when d.dtype = 1 then D.total end) AS TotReceipts,
        SUM(case when d.dtype = 0 then 1 end) AS Invoices, 
        SUM(case when d.dtype = 0 then D.total end) AS TotInvoices
FROM    
    documents D
    JOIN bills B ON (B.id = D.bill_id)
    JOIN waiters WA ON (WA.id = B.waiter_id)
GROUP BY 
    waiter_id

此查詢返回您提出的問題

 SELECT
    B.waiter_id,
    WA.name, 
    WA.surname,
    (select count(id)             from documents where dtype = 0 and bill_id = B.id) AS Invoices, 
    (select isnull(sum(total), 0) from documents where dtype = 0 and bill_id = B.id) AS TotInvoices, 
    (select count(id)             from documents where dtype = 1 and bill_id = B.id) AS Receipts, 
    (select isnull(sum(total), 0) from documents where dtype = 1 and bill_id = B.id) AS TotReceipts
  FROM bills B
 inner join waiters WA on WA.id = B.waiter_id

要匯總所有總計,您可以進行內部選擇,以便將總計總結為:

select  data.*, 
        data.Invoices + data.Receipts as docs,
        data.TotInvoices + data.TotReceipts as totaldocs
  from (
  select 
    B.waiter_id,
    WA.name, 
    WA.surname,
    (select count(id)             from documents where dtype = 0 and bill_id = B.id) AS Invoices, 
    (select isnull(sum(total), 0) from documents where dtype = 0 and bill_id = B.id) AS TotInvoices, 
    (select count(id)             from documents where dtype = 1 and bill_id = B.id) AS Receipts, 
    (select isnull(sum(total), 0) from documents where dtype = 1 and bill_id = B.id) AS TotReceipts
  from bills B
 inner join waiters WA on WA.id = B.waiter_id
 ) data

暫無
暫無

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

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