Reputation: 107
I have calculated the sum of a count in different tables. This is done twice, once for each performanceID
. Now I want to get the sum of the two sums.
Below is the code for the two sums that I do at the moment:
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
The results I get are:
TOTALAMOUNT ----------- 70 60
How do I sum up the two sums here?
Upvotes: 3
Views: 12131
Reputation: 52863
I'm never going to compete with the FGITW but I have to say something about this query...
If we add whitespace I hope you'll see what I mean:
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
Breaking the query down the only reason that you got two rows returned were the analytic functions and the union all.
booking
and production
, this means that you multiply the number of rows in each by each other.performance
are returning one value, which is already known. There's no reason to do them at all.It appears as though you want the total amount taken for each performance in which case your query can be simplified to the following:
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
)
Please note the explicit join syntax, this has been around for a few decades, makes things a lot clearer and helps stop mistakes. This query will do two range scans, one of booking
and one of production
, assuming you have indexes on performanceid
on both tables. It'll also do a unique scan of performance
assuming that performanceid
is the primary key of this table.
As an explanation of what this does, now I've finally managed to get your schema correct! We select the two performances, 1
and 2
. We then select every production related to those performances and every booking related to those productions. You may be able to simplify this further depending on what table categoryprice
is in. We then get the number of bookings per categoryprice
and sum the product of these to give you the total value.
As a bit of advice, I would always recommend understanding what values you expect to be returned from a query before you accept that your query is correct. The very best can and do make mistakes. Being able to catch them because you can see that the returned values are incorrect will help.
Upvotes: 7
Reputation: 6944
Use sub sql, and sum TotalAmount
SELECT SUM(TotalAmount)
( 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 CategoryPrice)
Upvotes: 0