如何将SQL更新语句组合到单个语句中

时间:2014-02-26 18:17:50

标签: sql sql-server optimization

我有以下SQL Server表。出于我的问题的目的,只有一个具有给定名称的“人”(Person,或Person + Year的组合是表的主键) 。

DailySalesSummary
+------+--------+---------+------+-------------+-------------+-----------+
| Year | Person | Family  | City | PersonSales | FamilySales | CitySales |
+------+--------+---------+------+-------------+-------------+-----------+
| 2013 | Jim    | Smith   |    1 | $10         | $10         | $10       |
| 2013 | Anna   | Smith   |    1 | $0          | $10         | $10       |
| 2013 | John   | Stewart |    3 | $8          | $8          | $13       |
| 2013 | Todd   | Johnson |    3 | $4          | $5          | $13       |
| 2013 | Alan   | Johnson |    3 | $1          | $5          | $13       |
+------+--------+---------+------+-------------+-------------+-----------+

SalesSummary
+------+--------+-------------+-----------+
| Year | Person | FamilySales | CitySales |
+------+--------+-------------+-----------+
| 2013 | Jim    | $55         | $55       |
| 2013 | Anna   | $55         | $55       |
| 2013 | John   | $24         | $39       |
| 2013 | Todd   | $10         | $39       |
| 2013 | Alan   | $5          | $39       |
+------+--------+-------------+-----------+

Reference
+--------+--------+------+
| Person | Family | City |
+--------+--------+------+
| Jim    | Smith  | 1    |
| …      | …      | …    |
+--------+--------+------+

我想用SalesSummary表的内容更新DailySalesSummary表。我是通过以下方式完成的:

UPDATE SalesSummary 
  SET FamilySales = SalesSummary.FamilySales + p.FamilySales 
FROM DailySalesSummary p,
     Reference bx
WHERE SalesSummary.Person= bx.Person
  AND bx.City = p.City
  AND bx.Family = p.Family
  AND SalesSummary.Year = p.Year

UPDATE SalesSummary
  SET CityTotal = SalesSummary.FamilyTotal + p.FamilyTotal
FROM DailySalesSummary p,
     Reference bx
WHERE SalesSummary.Person = bx.Person
  AND bx.City = p.City
  AND SalesSummary.Year = p.Year 

我想找到一种方法将两个更新语句组合成一个更新语句,它将处理所有事情,但我无法弄清楚所需的确切结构。

如果必要的解决方案非常简单,请道歉,但我感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以通过一次更新来完成此操作:

UPDATE SalesSummary
  SET FamilySales = SalesSummary.FamilySales + (case when bx.Family = p.Family then p.FamilySale else 0 end),
      CityTotal = SalesSummary.FamilyTotal + p.FamilyTotal
FROM DailySalesSummary p,
     Reference bx
WHERE SalesSummary.Person = bx.Person
  AND bx.City = p.City
  AND SalesSummary.Year = p.Year;

这会将FamilySales设置为与bx.Family = p.Family条件不匹配的行。但它应该与你的两个查询具有相同的效果。

编辑:

以下内容似乎适用于您拥有的数据:

UPDATE ss 
    set FamilySales = ss.FamilySales + dss.FamilySales,
        CitySales = ss.CitySales + dss.CitySales
FROM SalesSummary ss join
     DailySalesSummary dss
     on ss.Person = dss.Person and
        ss.City = dss.City
        ss.Family = dss.Family;

我不明白为什么有bx表的连接。如果你想过滤掉你的东西,你仍然可以这样做。

据我所知,DailySalesSummary中的数据与需要更新的内容一致,因此简单的join会将正确的行组合在一起。

答案 1 :(得分:0)

实际上,您不能UPDATE多个包含UPDATEUPDATE SalesSummary SET FamilySales = SalesSummary.FamilySales + p.FamilySales, CityTotal = SalesSummary.FamilyTotal + p.FamilyTotal FROM DailySalesSummary p, Reference bx WHERE SalesSummary.Person= bx.Person AND bx.City = p.City AND bx.Family = p.Family AND SalesSummary.Year = p.Year 语句的表。更多信息可以在this Stack Overflow回答中找到。

如果要更新的所有列都在同一个表中并来自相同的源表,那么您只需更新多个列,执行以下操作:

SQL 2000

虽然我不推荐UPDATE SalesSummary SET FamilySales = SalesSummary.FamilySales + p.FamilySales, CityTotal = SalesSummary.FamilyTotal + p.FamilyTotal FROM DailySalesSummary p JOIN Reference bx ON bx.City = p.City AND bx.Family = p.Family WHERE SalesSummary.Year = p.Year AND SalesSummary.Person = bx.Person - 样式连接。重做它看起来像这样:

UPDATE s
SET
    s.FamilySales = s.FamilySales + fam.FamilySales,
    s.CitySales = s.CitySales + city.CitySales
FROM
    SalesSummary s
    JOIN Reference r ON r.Person = s.Person
    JOIN (SELECT DISTINCT Year, Family, FamilySales FROM DailySalesSummary) fam ON fam.Family = r.Family AND fam.Year = s.Year
    JOIN (SELECT DISTINCT Year, City, CitySales FROM DailySalesSummary) city ON city.City = r.City AND city.Year = s.Year

更新答案

{{1}}

您可以看到a working example here at SQLFiddle