2011-05-03 73 views
1

只是簡單介紹一下業務場景,表格已創建好的收據。因此,我們在前幾行有PurchaseOrder(PO)的良好預期行。然後,我們收到每個預期的物理線路,那個時候這些數量可能會有所不同,由於像數量這樣的業務情況可能會造成損壞和短期的數量。因此,我們保持一個狀態,例如:OK,Damage,還需要根據每件物品的預計數量和收到的總數來計算短數量。SQL運行減法

if object_id('DEV..Temp','U') is not null 
    drop table Temp 

    CREATE TABLE Temp 
    (  
    ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,   
    Item VARCHAR(32), 
    PO VARCHAR(32) NULL,   
    ExpectedQty INT NULL, 
    ReceivedQty INT NULL, 
    [STATUS] VARCHAR(32) NULL, 
    BoxName VARCHAR(32) NULL 
    ) 

請參閱與PO數據前幾個行會的預期線, 然後休息線將接收線

INSERT INTO TEMP (Item,PO,ExpectedQty,ReceivedQty,[STATUS],BoxName) 
    SELECT 'ITEM01','PO-01','30',NULL,NULL,NULL UNION ALL 
    SELECT 'ITEM01','PO-02','20',NULL,NULL,NULL UNION ALL 
    SELECT 'ITEM02','PO-01','40',NULL,NULL,NULL UNION ALL 
    SELECT 'ITEM03','PO-01','50',NULL,NULL,NULL UNION ALL 
    SELECT 'ITEM03','PO-02','30',NULL,NULL,NULL UNION ALL 
    SELECT 'ITEM03','PO-03','20',NULL,NULL,NULL UNION ALL 
    SELECT 'ITEM04','PO-01','30',NULL,NULL,NULL UNION ALL 
    SELECT 'ITEM01',NULL,NULL,'20','OK','box01' UNION ALL 
    SELECT 'ITEM01',NULL,NULL,'25','OK','box02' UNION ALL 
    SELECT 'ITEM01',NULL,NULL,'5','DAMAGE','box03' UNION ALL 
    SELECT 'ITEM02',NULL,NULL,'38','OK','box04' UNION ALL 
    SELECT 'ITEM02',NULL,NULL,'2','DAMAGE','box05' UNION ALL 
    SELECT 'ITEM03',NULL,NULL,'30','OK','box06' UNION ALL 
    SELECT 'ITEM03',NULL,NULL,'30','OK','box07' UNION ALL 
    SELECT 'ITEM03',NULL,NULL,'30','OK','box08' UNION ALL 
    SELECT 'ITEM03',NULL,NULL,'10','DAMAGE','box09' UNION ALL 
    SELECT 'ITEM04',NULL,NULL,'25','OK','box10' 

下表是根據上面的數據我預期的結果。 我需要按以下方式顯示這些數據。 所以我很感激,如果你能給我一個適當的查詢。 注意:第一行是空白的,它實際上是我的表格標題。 :)

SELECT '' as 'ITEM', '' as 'PO#', '' as 'ExpectedQty', 
      '' as 'ReceivedQty','' as 'DamageQty' ,'' as 'ShortQty' UNION ALL 
    SELECT 'ITEM01','PO-01','30','30','0' ,'0' UNION ALL 
    SELECT 'ITEM01','PO-02','20','15','5' ,'0' UNION ALL 
    SELECT 'ITEM02','PO-01','40','38','2' ,'0' UNION ALL 
    SELECT 'ITEM03','PO-01','50','50','0' ,'0' UNION ALL 
    SELECT 'ITEM03','PO-02','30','30','0' ,'0' UNION ALL 
    SELECT 'ITEM03','PO-03','20','10','10','0' UNION ALL 
    SELECT 'ITEM04','PO-01','30','25','0' ,'5' 

注意:我們沒有收到超過預期。 解決方案應基於SQL 2000

+0

1.可有超過1一行'狀態=「DAMAGE''一個項目? 2.'OK'數量+'DAMAGE'數量總和是否超過預期數量(對於同一項目)的總數? – 2011-05-03 14:12:26

+0

3.是否有可能某個物品的「DAMAGE」總數超過了最後一行的預期數量? (例如,你樣本中'ITEM03'的'DAMAGE'總數是否可以達到21?我試圖弄清楚損害總量應該如何在行間分配。) – 2011-05-03 14:18:22

回答

1

您應該重新考慮如何存儲此數據。單獨的ExpectedReceived+Damaged在不同的表中(您有許多未使用的(null)單元格)。這樣任何查詢都應該變得更具可讀性。

我想你試圖做的事情可以通過存儲過程更容易地實現。

不管怎麼說,嘗試此查詢:

SELECT Item, PO, ExpectedQty, 
     CASE WHEN [rec-consumed] > 0 THEN ExpectedQty 
      ELSE CASE WHEN [rec-consumed] + ExpectedQty > 0 
         THEN [rec-consumed] + ExpectedQty 
         ELSE 0 
       END 
     END ReceivedQty, 
     CASE WHEN [rec-consumed] < 0 
       THEN CASE WHEN DamageQty >= -1*[rec-consumed] 
          THEN -1*[rec-consumed] 
          ELSE DamageQty 
         END 
      ELSE 0 
     END DamageQty, 
     CASE WHEN [rec_damage-consumed] < 0 
      THEN DamageQty - [rec-consumed] 
      ELSE 0 
     END ShortQty 
FROM (
    select t1.Item, 
      t1.PO, 
      t1.ExpectedQty, 
      st.sum_ReceivedQty_OK 
        - (sum(COALESCE(t2.ExpectedQty,0)) 
        +t1.ExpectedQty) 
       [rec-consumed], 
      st.sum_ReceivedQty_OK + st.sum_ReceivedQty_DAMAGE 
        - (sum(COALESCE(t2.ExpectedQty,0)) 
        +t1.ExpectedQty) 
       [rec_damage-consumed], 
      st.sum_ReceivedQty_DAMAGE DamageQty 
    from #tt t1 
    left join #tt t2 on t1.Item = t2.Item 
        and t1.PO > t2.PO 
        and t2.PO is not null 
    join (select Item 
      , sum(CASE WHEN status = 'OK' THEN ReceivedQty ELSE 0 END) 
       sum_ReceivedQty_OK 
      , sum(CASE WHEN status != 'OK' THEN ReceivedQty ELSE 0 END) 
       sum_ReceivedQty_DAMAGE 
     from #tt where PO is null 
     group by Item) st on t1.Item = st.Item 
    where t1.PO is not null 
    group by t1.Item, t1.PO, t1.ExpectedQty, 
      st.sum_ReceivedQty_OK, 
      st.sum_ReceivedQty_DAMAGE 
) a 
order by Item, PO