我已经计算了不同表中计数的总和。这会执行两次,每个 performanceID
一次。现在我想得到两个总和的总和。
下面是我目前做的两个总和的代码:
SELECT SUM((COUNT (BookingID) * CategoryPrice)) AS TotalAmount
FROM Booking, Production
WHERE Booking.PerformanceID IN(SELECT PerformanceID FROM Performance WHERE PerformanceID = '1')
and Production.ProductionID IN
(SELECT ProductionID FROM Performance WHERE PerformanceID = '1')
GROUP BY BookingID, CategoryPrice
UNION ALL
SELECT SUM((COUNT (BookingID) * CategoryPrice)) AS TotalAmount
FROM Booking, Production
WHERE Booking.PerformanceID IN(SELECT PerformanceID FROM Performance WHERE PerformanceID = '2')
and Production.ProductionID IN
(SELECT ProductionID FROM Performance WHERE PerformanceID = '2')
GROUP BY BookingID, CategoryPrice
我得到的结果是:
TOTALAMOUNT ----------- 70 60
我如何计算这里的两个总和?
最佳答案
我永远不会与 FGITW 竞争,但我必须对这个查询说点什么......
如果我们添加空格,我希望你能明白我的意思:
SELECT SUM( (COUNT(BookingID) * CategoryPrice) ) AS TotalAmount
FROM Booking
, Production
WHERE Booking.PerformanceID IN ( SELECT PerformanceID
FROM Performance
WHERE PerformanceID = '1')
AND Production.ProductionID IN ( SELECT ProductionID FROM Performance
WHERE PerformanceID = '1')
GROUP BY BookingID, CategoryPrice
UNION ALL
SELECT SUM( (COUNT(BookingID) * CategoryPrice)) AS TotalAmount
FROM Booking
, Production
WHERE Booking.PerformanceID IN ( SELECT PerformanceID
FROM Performance
WHERE PerformanceID = '2')
AND Production.ProductionID IN ( SELECT ProductionID
FROM Performance
WHERE PerformanceID = '2')
GROUP BY BookingID, CategoryPrice
将查询分解为返回两行的唯一原因是分析函数和 union all。
- 你正在做一个 cartesian join在
booking
和production
之间,这意味着您将彼此中的行数相乘。 - 您对
performance
的子选择返回一个已知值。根本没有理由这样做。 - 您正在隐式地将数字转换为字符串,然后再转换回数字。
- 您正在此处扫描表或索引 8 次!
看起来好像您想要每次表演的总金额,在这种情况下,您的查询可以简化为以下内容:
SELECT SUM(bookings * CategoryPrice)
FROM ( SELECT CategoryPrice , count(*) as bookings
FROM Booking b
JOIN performance per
ON p.performanceid = per.performanceid
JOIN Production p
ON p.productionid = per.productionid
WHERE p.performanceid in (1, 2)
GROUP BY CategoryPrice
)
请注意显式连接语法,这已经存在了几十年,使事情变得更加清晰并且 helps stop mistakes .此查询将进行两次范围扫描,一次是 booking
,一次是 production
,假设您在两个表上都有关于 performanceid
的索引。假定 performanceid
是该表的主键,它还会对 performance
进行唯一扫描。
作为对它的作用的解释,现在我终于设法使您的架构正确无误!我们选择了两个性能,1
和 2
。然后,我们选择与这些表演相关的每个制作以及与这些制作相关的每个预订。根据 categoryprice
所在的表,您可以进一步简化此过程。然后我们获取每个 categoryprice
的预订数量,并将这些乘积相加得到总数值(value)。
作为一点建议,我总是建议您在接受您的查询是正确的之前了解您期望从查询返回的值。最优秀的人可以而且确实会犯错误。能够捕捉到它们,因为您可以看到返回值不正确,这将有所帮助。
进一步阅读:
- Join (SQL) - 维基百科
- A Visual Explanation of SQL Joins - 编程恐怖
- In Function - 网络技术
关于SQL 总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10469941/