【问题标题】:SQL update within same table based on summation基于求和的同一张表内的SQL更新
【发布时间】:2013-12-27 15:05:30
【问题描述】:

我有这张表叫t,如下图。

   cust_id|    brand|    bill_amt|       AA|        BB|
   1234   |       AA|         100|     NULL|      NULL|
   5678   |       AA|         300|     NULL|      NULL|
   5678   |       BB|         350|     NULL|      NULL|
   5678   |       BB|         600|     NULL|      NULL|

我的数据中有大约数十万条记录,我是否可以更新 t 表,如下所示?

   cust_id|    brand|    bill_amt|       AA|        BB|
   1234   |       AA|         100|      100|      NULL|
   5678   |       AA|         300|      300|       950|
   5678   |       BB|         350|      300|       950|
   5678   |       BB|         600|      300|       950|

如何在 AA 和 BB 列下显示 bill_amt 值?
我如何总结同一客户在品牌上花费的 bill_amt?

例如,查看客户 5678,她在不同的日子为品牌 BB 花费了 $350 和 $600,我如何在 BB 列中显示她为 BB 花费的 bill_amt 的总和?
另外,同一位客户在 AA 上花费了 300 美元,我如何在 AA 列中显示这个值?

【问题讨论】:

  • 您是否考虑过使用嵌套查询来汇总和更新指定列?
  • 你只有两个品牌?
  • 我有2个以上的品牌,但只是希望简化上表。
  • 问题是。你为什么还要考虑这个?您的 db 架构似乎是错误的,因为当您应该努力避免重复时,您会产生大量数据冗余。当您可以在“运行时”计算总量时,为什么需要存储总量?这些合计金额(或总计)似乎不属于每条记录(行),因为您的记录代表金融交易,而总计不是每笔交易的属性。
  • 没有办法简化它,除非不要这样做。您可以相对容易地将 tehb 运行总计作为数据透视表/交叉表,但将它们作为交叉表保留是一个非常糟糕的主意。事实上,在维护基础数据的系统中持久保存任何运行总计充其量只是一个障碍。无论如何,您将不得不一直重新计算所有这些。

标签: sql-server-2008 group-by sql-update sum duplicates


【解决方案1】:

要选择汇总而不实际在表中创建汇总字段,您可以简单地使用OVER;将其创建为视图很可能会在不更改表格的情况下为您带来相同的优势。

SELECT CUST_ID, BRAND, BILL_AMT, 
  SUM(CASE WHEN brand='AA' THEN bill_amt ELSE NULL END) 
    OVER (PARTITION BY cust_id) AA,
  SUM(CASE WHEN brand='BB' THEN bill_amt ELSE NULL END) 
    OVER (PARTITION BY cust_id) BB
FROM t;

要真正更新表,您可以使用通用表表达式,但是我真诚地建议不要这样做,除非历史数据可能永远不会改变,因为对数据的更改将不再自动更新摘要。

WITH cte AS (
  SELECT *,
    SUM(CASE WHEN brand='AA' THEN bill_amt ELSE NULL END) 
      OVER (PARTITION BY cust_id) AA2,
    SUM(CASE WHEN brand='BB' THEN bill_amt ELSE NULL END) 
      OVER (PARTITION BY cust_id) BB2
  FROM t
) 
UPDATE cte SET AA=AA2, BB=BB2;

An SQLfiddle for testing both ways.

【讨论】:

  • 很好,不过和我要发布的问题一样,每个品牌 = 更多 sql。
  • @TonyHopkinson 是的,你是对的,我刚刚阅读了上面关于 2 个以上品牌的 cmets,从原始问题的角度来看。
  • 我也是,现在停止了,尤其是看到你的答案比我的好。
猜你喜欢
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
相关资源
最近更新 更多