【问题标题】:Sum or join rows by criteria按条件求和或连接行
【发布时间】:2016-03-15 07:15:20
【问题描述】:

假设我有这样一张桌子:

表1

 EmployeeID   Month          sym      Quantity       V_M       BudjetCode
    222222            1           40          133.35    1214          800000
    222222            2           40         178.50     115           800000
    222222            3           40         150.33     215           800000
    222222            4           40         186.37     315           800000
    222222            5           40         127.38     415           800000
    222222            6           40         153.00     515           800000
    222222            7           40         178.50     615           800000
    222222            7           40          8.50      615         700052015
    222222            8           40         187.00     715          800000

我想把这张表改成:

表 2

EmployeeID    Month          sym      Quantity          V_M           BudjetCode
        222222            1           40          133.35    1214          800000
        222222            2           40         178.50     115           800000
        222222            3           40         150.33     215           800000
        222222            4           40         186.37     315           800000
        222222            5           40         127.38     415           800000
        222222            6           40         161.5      515           800000
        222222            7           40         178.50     615           800000
        222222            8           40         187.00     715          800000

怎么样? 请参阅表 1 中 BudjetCode 异常的行?

好吧,对于这一行,我想将 Quantity 值 (8.5) 添加到 V_M 比 V_M 小一的行是原始行(其中 budjetCode 为 700052015)。

在示例中,原来是 615,所以减一是 515(615 表示日期 6.15,515 表示 5.15),我需要添加数量(8.5 到 153 = 161.5)

我在想“过度分区”:

select [EmployeeID],[Month],[Sym],
sum([Quantity]) 
over (partition by [EmployeeID], [V_M]-1 where???) as b
from table1 
where [Sym] = '40' and [EmployeeID] = 222222
order by [Month]

但我不知道如何使用 budjetCode 以“700”开头的标准来总结。

评论:不要在第一行这样做。

更新:

EmployeeID month Quantity V_M   MS_BudjetCode
22222   1   40  133.35  1214    88888888
22222   2   40  178.50  115 88888888
22222   3   40  150.33  215 88888888
22222   4   40  186.37  315 88888888
22222   5   40  127.38  415 88888888
22222   6   40  153.00  515 88888888
22222   7   40  8.50    615 700000000
22222   7   40  178.50  615 88888888
22222   8   40  187.00  715 88888888

输出:

22222   2   40  178.50  115 88888888
22222   4   40  186.37  315 88888888
22222   8   40  187.00  715 88888888
22222   3   40  151.33  215 88888888
22222   3   40  151.33  215 88888888
22222   3   40  151.33  215 88888888
22222   3   40  149.33  215 88888888
22222   3   40  149.33  215 88888888
22222   5   40  127.38  415 88888888
22222   6   40  152.00  515 88888888
22222   6   40  154.00  515 88888888
22222   6   40  152.00  515 88888888
22222   6   40  154.00  515 88888888
22222   6   40  154.00  515 88888888
22222   6   40  152.00  515 88888888
22222   6   40  161.50  515 88888888
22222   7   40  178.50  615 88888888
22222   1   40  133.35  1214    88888888

查询:

SELECT t1.EmployeeID, t1.Month, t1.sym, 
       t1.Quantity + COALESCE(t2.Quantity, 0), 
       t1.V_M, t1.BudjetCode 
FROM Table1 AS t1
LEFT JOIN Table1 AS t2 
  ON t1.EmployeeID = t2.EmployeeID AND t1.V_M = t2.V_M - 100 AND 
     SUBSTRING(t2.BudjetCode,1,3) = '700'
WHERE SUBSTRING(t1.BudjetCode,1,3) <> '700' and sym='40' and EmployeeID = 22222

【问题讨论】:

    标签: sql sql-server-2008 select sql-update


    【解决方案1】:

    这可能是一个解决方案,我认为我们不能简单地用月份减去 1,还需要考虑 1 月 12 月的情况。我也包括了那个检查。这里的budgetcode以长度来区分,你可以根据需要改变它。

    ;WITH CTETable1 AS ( SELECT EmployeeID,[Month],sym, CASE WHEN LEN(BudjetCode)>6 THEN Quantity ELSE 0 END Quantity, CASE WHEN LEN(BudjetCode)>6 THEN (CASE WHEN LEFT(V_M,LEN(V_M)-2)=1 THEN 12 ELSE LEFT(V_M,LEN(V_M)-2)-1 END)*100+ (CASE WHEN LEFT(V_M,LEN(V_M)-2)=1 THEN RIGHT(V_M,2)-1 ELSE RIGHT(V_M,2) END) ELSE 0 END V_M, BudjetCode FROM Table1 ) SELECT T1.EmployeeID,T1.[Month],T1.sym,T1.Quantity+ISNULL(T2.Quantity,0) Quantity, T1.V_M,T1.BudjetCode FROM Table1 T1 LEFT JOIN CTETable1 T2 ON T1.EmployeeID=T2.EmployeeID AND T1.V_M=T2.V_M WHERE LEN(T1.BudjetCode)=6

    【讨论】:

    • 谢谢 但是 LEN(BudjetCode)>6 表示异常记录?
    • 我怎样才能限制为 sym ='40'?
    • 您可以通过添加 where 子句来限制为 sym ='40'
    【解决方案2】:

    这会解决您的问题吗?

    DELETE
    FROM
    table
    WHERE BudjetCode='700052015'
    

    UPDATE table
    SET Quantity = (Quantity+8.5)
    WHERE Month = 6;
    

    【讨论】:

    • 如果有行在 where 子句中包含同样的数据,请确保包含 ID 号。这样一来,您所做的更改就不会超出预期。
    【解决方案3】:

    我认为你可以使用简单的LEFT JOIN 操作来做你想做的事:

    SELECT t1.EmployeeID, t1.Month, t1.sym, 
           t1.Quantity + COALESCE(t2.Quantity, 0), 
           t1.V_M, t1.BudjetCode 
    FROM Table1 AS t1
    LEFT JOIN Table1 AS t2 
      ON t1.EmployeeID = t2.EmployeeID AND t1.V_M = t2.V_M - 100 AND 
         SUBSTRING(t2.BudjetCode,1,3) = '700'
    WHERE SUBSTRING(t1.BudjetCode,1,3) <> '700'
    

    查询选择所有表行“不寻常”行,并提前一天(或者可能是一小时?)将它们与“不寻常”行连接起来。 Quantity 返回的是“正常”行的值加上相关“不寻常”行的值的总和(如果确实存在的话)。

    表达式:

    t1.V_M = t2.V_M - 100
    

    V_Mof t1t2 之间实现一个关系。您可以根据实际需要进行更改。

    Demo here

    【讨论】:

    • 谢谢。有什么理由让结果翻倍?我得到:1 133.35, 178.5, 149.33, 151.33, 186.37, 127.38,152,154,161.5, 178.5, 187。
    • @Jordan1200 你的真实数据肯定有一些不同。你检查过我做的演示吗?你能修改它以包含这种“数据加倍”的情况吗?
    • 您是否在表 1 上运行查询并得到准确的表 2?
    • @Jordan1200 是的,我做到了。你检查了我设置的演示吗?它恰恰证明了这一点。让我知道演示中是否有问题。
    • 嘿,我更新了我的初始帖子。请在那里查看我的输出。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多