sql - sql server中带有case语句的更新查询中的聚合函数

标签 sql sql-server

我正在尝试使用聚合函数和 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/

相关文章:

sql - 使用 select * 的递归查询引发 ORA-01789

sql - 在 T-SQL 中组合存储过程和查询

SQL Server 2008 : replace string

sql - 表函数中的条件 UNION ALL

sql - 是否可以在主键不等于 column4 的表上写约束

mysql - 语法错误 : WITH is not valid input in this position

sql - Entity Framework 迁移 - 分支管理

sql - @@IDENTITY、SCOPE_IDENTITY()、OUTPUT 和其他检索最后身份的方法

mysql - JOOQ多集抛出语法异常

php - 还有比从 GROUP_CONCAT 结果中收集 ID 并运行第二个查询来获取一对多数据更好的做法吗?