我正在尝试使用聚合函数和 case 语句编写更新查询。 我是如何陷入困境的
最初我编写了以下查询,这给了我错误,“聚合函数不能在更新语句中使用
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 值('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 - sql server中带有case语句的更新查询中的聚合函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51943155/