簡體   English   中英

更新查詢中的聚合函數與 sql server 中的 case 語句

[英]Aggregate function in update query with case statement in sql server

我正在嘗試使用聚合函數和 case 語句編寫更新查詢。 一些我是如何卡住的

最初我寫了以下查詢,這給了我錯誤tha,“聚合函數不能在更新語句中使用

UPDATE report
SET report.LoadDischargeQty = 
CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'D' AND cargo.CRG_Quantity is NOT NULL THEN cargo.CRG_Quantity 
 ELSE
     CASE WHEN report.PlaId = 'LP' THEN 
                                    CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'D' THEN ISNULL(SUM(CRG_SFgrMT),0) END -  
                                    CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'A' THEN ISNULL(SUM(CRG_SFgrMT),0)END 
         WHEN report.PlaId = 'DP' THEN 
                                    CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'A' THEN ISNULL(SUM(CRG_SFgrMT),0) END-
                                    CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'D' THEN ISNULL(SUM(CRG_SFgrMT),0)END
        ELSE 0 END  
END 
from #CargoPerformanceReport report
INNER JOIN POSCARGO cargo ON cargo.POS_ID = report.PositionId AND ISNULL(cargo.CRG_Deleted,0)=0

所以我將它重構如下

UPDATE report
SET report.LoadDischargeQty = 
CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'D' AND cargo.CRG_Quantity is NOT NULL THEN cargo.CRG_Quantity 
 ELSE
    select quantity.dischargeQuantity from (SELECT CASE WHEN report.PlaId = 'LP' THEN 
                                    CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'D' THEN ISNULL(SUM(CRG_SFgrMT),0) END -  
                                    CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'A' THEN ISNULL(SUM(CRG_SFgrMT),0)END 
         WHEN report.PlaId = 'DP' THEN 
                                    CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'A' THEN ISNULL(SUM(CRG_SFgrMT),0) END-
                                    CASE WHEN SUBSTRING(CRG_ArrDep,1,1) = 'D' THEN ISNULL(SUM(CRG_SFgrMT),0)END
        ELSE 0 END  dischargeQuantity ) quantity
END 
from #CargoPerformanceReport report
INNER JOIN POSCARGO cargo ON cargo.POS_ID = report.PositionId AND ISNULL(cargo.CRG_Deleted,0)=0

表結構

CREATE TABLE #CargoPerformanceReport
(
    PositionId              VARCHAR(12),
    PortAndActivityName     VARCHAR(100),
    PlaId                   VARCHAR(12),
    LoadDischargeQty            REAL,

);

插入#CargoPerformanceReport Values('100',null,'LP',null)

CREATE TABLE #Poscargo
(
    POS_ID              VARCHAR(12),
    CRG_ArrDep          VARCHAR(3),
    CRG_SFgrMT          REAL,
    CRG_Quantity        REAL,
    CRG_Deleted         BIT
);


Insert Into #Poscargo(POS_ID,CRG_ArrDep,CRG_SFgrMT,null,0)
Values ('100','DD',100)

Insert Into #Poscargo(POS_ID,CRG_ArrDep,CRG_SFgrMT)
Values ('100','AD',100)

Insert Into #Poscargo(POS_ID,CRG_ArrDep,CRG_SFgrMT)
Values ('100','DD',200)

Insert Into #Poscargo(POS_ID,CRG_ArrDep,CRG_SFgrMT)
Values ('100','AD',50)


Insert Into #Poscargo(POS_ID,CRG_ArrDep,CRG_SFgrMT)
Values ('101','DL',200)


Insert Into #Poscargo(POS_ID,CRG_ArrDep,CRG_SFgrMT)
Values ('101','AL',200)

SELECT * FROM #Poscargo
SELECT * FROM #CargoPerformanceReport

結果:-

PositionId |    PlaId | LoadDischargeQty
100        |     LP   | 150

但這不是正確的方法,也有錯誤。

有沒有人為此優化過解決方案?

將所有這些東西放入子查詢中:

SELECT LoadDischargeQty = 
  CASE 
    WHEN report.PlaId = 'LP' 
    THEN 1 
    ELSE -1 
  END * cargo.qty
FROM CargoPerformanceReport report
CROSS APPLY(
  SELECT SUM(
    CASE 
      WHEN CRG_ArrDep LIKE 'D%' 
      THEN 1 
      WHEN CRG_ArrDep LIKE 'A%' 
      THEN -1 
      ELSE 0
    END * ISNULL(CRG_SFgrMT, 0)
    ) qty
  FROM POSCARGO cargo
  WHERE cargo.POS_ID = report.PositionId 
    AND ISNULL(cargo.CRG_Deleted,0)=0
) cargo

http://sqlfiddle.com/#!18/648d0/7

我不明白應該如何使用CRG_Quantity列,並且您沒有提供包含該數據的任何行,因此我將其刪除以向您展示聚合本身。 工作正常,您將獲得 150。您可以輕松地將其轉換為update語句。

也許像這樣?
它使用帶有匯總案例的案例。

此處測試 SQL Fiddle

UPDATE t
SET LoadDischargeQty = q.CalcDischargeQty
FROM #CargoPerformanceReport t
JOIN
(
    SELECT report.PositionId, report.PlaId,
    CASE 
    WHEN SUM(CASE WHEN LEFT(cargo.CRG_ArrDep,1) = 'D' THEN cargo.CRG_Quantity END) IS NOT NULL 
    THEN SUM(CASE WHEN LEFT(cargo.CRG_ArrDep,1) = 'D' THEN cargo.CRG_Quantity END)
    ELSE CASE 
         WHEN report.PlaId = 'LP' 
         THEN SUM(CASE WHEN LEFT(cargo.CRG_ArrDep,1) = 'D' THEN cargo.CRG_SFgrMT END) -  
              SUM(CASE WHEN LEFT(cargo.CRG_ArrDep,1) = 'A' THEN cargo.CRG_SFgrMT END) 
         WHEN report.PlaId = 'DP' 
         THEN SUM(CASE WHEN LEFT(cargo.CRG_ArrDep,1) = 'A' THEN cargo.CRG_SFgrMT END) -  
              SUM(CASE WHEN LEFT(cargo.CRG_ArrDep,1) = 'D' THEN cargo.CRG_SFgrMT END) 
         ELSE 0
         END
    END AS CalcDischargeQty
    FROM #CargoPerformanceReport report
    INNER JOIN #Poscargo cargo 
       ON cargo.POS_ID = report.PositionId AND (cargo.CRG_Deleted = 0 OR cargo.CRG_Deleted IS NULL)
    GROUP BY report.PositionId, report.PlaId
) q ON t.PositionId = q.PositionId;

樣本數據

IF OBJECT_ID('tempdb..#CargoPerformanceReport') IS NOT NULL DROP TABLE #CargoPerformanceReport;
CREATE TABLE #CargoPerformanceReport
(
    PositionId          VARCHAR(12) PRIMARY KEY,
    PortAndActivityName VARCHAR(100),
    PlaId               VARCHAR(12),
    LoadDischargeQty    REAL
);

IF OBJECT_ID('tempdb..#Poscargo') IS NOT NULL DROP TABLE #Poscargo;
CREATE TABLE #Poscargo
(
    POS_ID       VARCHAR(12),
    CRG_ArrDep   VARCHAR(3),
    CRG_SFgrMT   REAL,
    CRG_Quantity REAL,
    CRG_Deleted  BIT
);

Insert into #CargoPerformanceReport Values 
('100','name1','LP',null),
('101','name2','DP',null),
('102','name3','DP',null);

Insert Into #Poscargo(POS_ID, CRG_ArrDep, CRG_SFgrMT, CRG_Quantity, CRG_Deleted) Values 
 ('100','DD',100,null,0)
,('100','AD',100,null,0)
,('100','DD',200,null,0)
,('100','AD',50,null,0)
,('101','DL',100,null,0)
,('101','AL',200,null,0)
,('102','DL',100,500,0)
,('102','AL',200,null,0);

結果

PositionId PortAndActivityName PlaId LoadDischargeQty
---------- ------------------- ----- ----------------
100        name1               LP    150
101        name2               DP    100
102        name3               DP    500

暫無
暫無

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

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