我正在尝试使用聚合函数和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 值('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
但这不是正确的方法,并且也有错误。
有人为它优化了解决方案吗?
答案 0 :(得分:1)
将所有内容放入子查询:
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
我不知道应该如何使用CRG_Quantity
列,并且您没有向该行提供任何数据,因此我将其删除以向您显示聚合本身。工作正常,您将得到150。您可以轻松地将其转换为update
语句。
答案 1 :(得分:1)
也许是这样吗?
它使用具有汇总案例的案例。
在SQL Fiddle here上进行测试
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