Reputation: 6540
I have a number of queries that I would like to combine into a single query, even though they have a common filtering field, I am not completely sure that what I am trying to achieve is even possible since these are all aggregate queries.
declare @salesforceId int
set @salesforceId = 109924
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 1 --general feedback
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 3 --food rating
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 4 --drinks rating
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 5 -- restaurant ambience
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 6 -- service rating
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 7 -- booking service
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 12 -- Recommend Restaurant
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 13 -- Overall Rating
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 525 -- Value for Money
AND sr.RestaurantNetworkId = @salesforceId
SELECT
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND qr.QuestionId = 526 -- Location
AND sr.RestaurantNetworkId = @salesforceId
SELECT
count(*) as Total,
CultureInvariantText AS Tag
FROM
SurveyResponse SR
INNER JOIN
[QuestionResponseFixedOptions] QR ON SR.SurveyResponseId = QR.SurveyResponseId
INNER JOIN
QuestionResponseOption QRO ON QR.[ResponseOptionId] = QRO.[ResponseOptionId]
INNER JOIN
Question Q ON QRO.QuestionId = Q.QuestionId
INNER JOIN
LocalizableText LT ON QRO.ResponseValue = LT.LocalizableTextId
where sr.RestaurantNetworkId = @salesforceId
group by CultureInvariantText
output can be something along the lines of the following: count is the same across all queries.
|GeneralFeedback|FoodRating|....|.....|....|Count|
Upvotes: 0
Views: 203
Reputation: 45106
try group by
declare @salesforceId int
set @salesforceId = 109924
SELECT qr.QuestionId,
AVG(CAST(qr.RatingScaleOptionId as float)) as Rating,
COUNT(*) as ReviewCount
FROM QuestionResponse qr
JOIN SurveyResponse sr ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND sr.RestaurantNetworkId = @salesforceId
group by qr.QuestionId
Upvotes: 0
Reputation: 89
Try this. Please note that I changed the float for decimal
. You will have better precision, depending on which kind of application you are working for.
You need to finalize the query according to your ~10 cases.
SELECT AVG( CASE WHEN qr.QuestionId = 1 THEN CAST(qr.RatingScaleOptionId as decimal) END as GeneralFeedback_Rating
, COUNT(CASE WHEN qr.QuestionId = 1 THEN 1 END) as GeneralFeedback_Count
, AVG( CASE WHEN qr.QuestionId = 3 THEN CAST(qr.RatingScaleOptionId as decimal) END as Food_Rating
, COUNT(CASE WHEN qr.QuestionId = 3 THEN 1 END) as Food_Count
, AVG( CASE WHEN qr.QuestionId = 4 THEN CAST(qr.RatingScaleOptionId as decimal) END as Drinks_Rating
, COUNT(CASE WHEN qr.QuestionId = 4 THEN 1 END) as Drinks_Count
-- ... ... ...
FROM QuestionResponse qr
JOIN SurveyResponse sr
ON qr.SurveyResponseId = sr.SurveyResponseId
AND sr.StatusId IN (5, 7)
AND sr.RestaurantNetworkId = @salesforceId
AND qr.QuestionId IN (1, 3, 4)--1:general feedback, 3:food, 4:drinks, ETC...
Upvotes: 0
Reputation: 8746
If they are all accessing the same table, you should do conditional aggregates:
AVG(CAST CASE WHEN <condtion> THEN qr.RatingScaleOptionId END as float)
You can have as many of those in your SELECT
clause you like. Just make sure to only keep the common conditions in the WHERE
clause. The varying conditions then belong into the WHEN
of the CASE
.
Read more about this here: https://modern-sql.com/feature/filter
Upvotes: 1
Reputation: 727067
You can add a surrogate column for telling which aggregate a row represents, format each query to produce identical rows, and use UNION ALL
to combine them:
SELECT 'GeneralFeedback' AS Type, AVG(...) AS Rating, COUNT(*) AS ReviewCount
FROM QuestionResponse ...
UNION ALL
SELECT 'FoodRating' AS Type, AVG(...) AS Rating, COUNT(*) AS ReviewCount
FROM QuestionResponse ...
...
UNION ALL
SELECT 'Total' as Type, 0 as Rating, COUNT(*) as ReviewCount
FROM SurveyResponse ...
The row for the 'Total'
is "shoehorned" into the common structure by adding a column with zero rating and calling Total
a ReviewCount
. The code that executes this query will need special processing to treat this row separately from other rows coming back from the query.
Upvotes: 0