簡體   English   中英

如何從總和中排除行,但仍顯示行?

[英]How to exclude rows from sum but still show them?

我有一個表itemsInShippment其中包含以下數據:

itemid shippmentid qty
10         1       100
20         1       200
10         2       300
10         3       1000

和餐桌shippments

shippmentid date         shippmentstatus    supplierid
1           2015-01-12         OK               5000
2           2015-01-17         OK               5000
3           2015-01-17         Cancelled        5000

我需要編寫一個查詢,以顯示有關特定shipmentid 1詳細信息,例如shipmentid 1 我給定的參數是supplieriddate 它們一起涉及一個裝運(唯一)。

對於supplierid=5000date=2015-01-12我想獲得:

itemid        qty               qtyInOtherShipments
10            100                    300                      //1000 is canceled.
20            200                      0                       

我的查詢工作正常,而無需考慮已取消:

SELECT cte.* 
FROM 
    (SELECT
         a.itemid, b.date, a.qty,
         (coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid), 0) - 
          coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid, a.shipmentid)  ,0)  ) AS qtyInOtherShipments,
     FROM
         itemsInShippment a
     LEFT JOIN
         shippments b using (shippmentid)
     WHERE 
         b.supplierid = 5000) AS cte
  WHERE 
      cte.date = '2015-01-12'

cte必須以這種方式qtyInOtherShipments我總結的總qty ,然后刪除我自己的qty 為了求總qty我不能在WHERE d.date=...內部執行,我必須在外部執行。

該查詢給出:

itemid        qty               qtyInOtherShipments
10            100                    1300
20            200                    0

我在考慮cancelled發貨時遇到麻煩。 如果我改變Where到:

where b.supplierid = 5000 and b.shippmentstatus not like 'cancelled'

它有效...我將看到:

itemid        qty               qtyInOtherShipments
10            100                    300              
20            200                      0   

但是,如果我對已取消的發貨運行查詢( supplierid=5000 and date=2015-01-17 ),我將得到:

itemid        qty               qtyInOtherShipments
nothing

我應該得到的是:

itemid        qty               qtyInOtherShipments
10            1000                      300

所以我的問題是我不想對與canceled相關的itemid求和,但我仍然希望看到此行。

如何獲得正確的結果?

您只想從總和中排除已取消的項目。 因此,不要用where過濾它們,而只將它們過濾為總和:

SUM(case when b.shippmentstatus <> 'cancelled' then a.qty end) OVER (PARTITION BY ...

Sum不考慮null,這就是上面的工作原理的原因。 (取消狀態后,case表達式將返回null。)

對於PostgreSQL 9.4,存在一個更有效的Florian答案的變體,即聚合的filter子句。

SUM (a.qty) FILTER (WHERE b.shippmentstatus <> 'cancelled') OVER (PARTITION BY ...

有關匯總,請參見文檔中的FILTER 它基本上是一個mini- WHERE子句,僅適用於該聚合。

感謝@a_horse_with_no_name早點指出了它。

嘗試以下查詢

create table #itemsInShippment (itemid int, shippmentid int, qty int)

insert into #itemsInShippment (itemid, shippmentid, qty)
SELECT 10 as itemid,   1 as shippmentid,       100 as qty  UNION
SELECT 20  ,   1,       200   UNION
SELECT 10  ,   2,      300   UNION
SELECT 10  ,   3,      1000


CREATE TABLE #shippments (shippmentid int , dt date,  shippmentstatus varchar(50),    supplierid int)

insert into #shippments (shippmentid, dt, shippmentstatus,supplierid)
SELECT 1 as shippmentid,     '2015-01-12' as dt,         'OK' as shippmentstatus    ,           5000 as supplierid UNION ALL
SELECT 2,           '2015-01-17',         'OK'      ,         5000 UNION ALL
SELECt 3,           '2015-01-17' ,        'Cancelled'   ,     5000 




SELECT cte.* 
    FROM (

          select a.itemid,b.dt,a.qty,
                 (coalesce( SUM(case when shippmentstatus <> 'Cancelled' then a.qty else 0 end) OVER (PARTITION BY a.itemid)  ,0) - 
                   coalesce( SUM(case when shippmentstatus <> 'Cancelled' then a.qty else 0 end) OVER (PARTITION BY a.itemid,a.shippmentid)  ,0)  )
                   AS qtyInOtherShipments
          from #itemsInShippment a
          left join #shippments b on a.shippmentid = b.shippmentid                                 
          where b.supplierid = 5000  --and shippmentstatus = 'Cancelled'
        ) as cte
  where cte.dt='2015-01-12'

暫無
暫無

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

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