基于求和的同一表内的SQL更新

时间:2013-12-27 15:05:31

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

我有这个名为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栏中显示此值?

1 个答案:

答案 0 :(得分:3)

要选择摘要而不在表格中实际创建摘要字段,您只需使用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