2
\$\begingroup\$

The query works fine but I'm just intrigued to know if there is a cleaner solution. The data are results from a survey and I'm obtaining the counts per question within a zone and an overall zone count.

With Cte1 (ZoneId, QuestionId, Count1)
AS
(
 Select 
 tz.ZoneId, 
 qn.QuestionId,
 Count(1) as Count1
 From 
 Customers cust 
 Inner Join Shops td on td.ShopCode = cust.ShopCode
 Inner Join Zones tz on tz.Id = td.SlsZone
 Inner Join Responses res on res.SampleId = cust.SampleId
 Inner Join QstNodes qn on qn.QuestionId = res.QstNodeId
 Where 
 Event >= 201201 And Event <= 201212
 Group BY 
 tz.ZoneId, qn.QuestionId
)
SELECT 
 ZoneId,
 QuestionId
 Count1, 
 (
 SELECT SUM(Count1)
 FROm Cte1 as innercte
 Where innercte.ZoneId = outercte.ZoneId 
 )
 as ZoneTotal
FROM 
 Cte1 outercte
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Jan 24, 2013 at 15:26
\$\endgroup\$
2
  • 1
    \$\begingroup\$ The answer to your question is rollup, but that depends on the database that you are using. \$\endgroup\$ Commented Jan 24, 2013 at 15:31
  • \$\begingroup\$ @Gordon Linoff. Rollup was the the answer to my question. thanks \$\endgroup\$ Commented Jan 24, 2013 at 16:48

2 Answers 2

1
\$\begingroup\$

Using OVER, you can do it in one pass:

With Cte1 (ZoneId, QuestionId, Count1, sum1, rn)
AS
(
 Select 
 tz.ZoneId, 
 qn.QuestionId 
 , COUNT(1) OVER(PARTITION BY tz.ZoneId, qn.QuestionId) AS "Count1" 
 , COUNT(1) OVER(PARTITION BY tz.ZoneId) AS "Sum1"
 , row_number() OVER(PARTITION BY tz.ZoneId, qn.QuestionId order by ShopCode) AS "rn"
 From 
 Customers cust 
 Inner Join Shops td on td.ShopCode = cust.ShopCode
 Inner Join Zones tz on tz.Id = td.SlsZone
 Inner Join Responses res on res.SampleId = cust.SampleId
 Inner Join QstNodes qn on qn.QuestionId = res.QstNodeId
 Where 
 Event >= 201201 And Event <= 201212
)
SELECT *
FROM 
 Cte1 outercte 
where 
 rn = 1;
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
answered Aug 14, 2016 at 6:35
\$\endgroup\$
5
  • \$\begingroup\$ Answers should review the original code, not just present a code snippet. \$\endgroup\$ Commented Aug 14, 2016 at 6:38
  • \$\begingroup\$ @Jamal That is not a snippet. That is complete code. Check my SQL related rep on stackoverflow. \$\endgroup\$ Commented Aug 14, 2016 at 6:46
  • \$\begingroup\$ What I mean is, answers here shouldn't just contain code. \$\endgroup\$ Commented Aug 14, 2016 at 6:48
  • \$\begingroup\$ @Jamal If that intro is not enough feel free to delete \$\endgroup\$ Commented Aug 14, 2016 at 7:10
  • \$\begingroup\$ Good enough for me. \$\endgroup\$ Commented Aug 14, 2016 at 7:12
3
\$\begingroup\$

how about using CASE

SELECT tz.ZoneId,
 qn.QuestionId,
 SUM(CASE WHEN Event >= 201201 AND Event <= 201212
 THEN 1 
 ELSE 0
 END) as Count1,
 COUNT(*) AS ZoneTotal
FROM Customers cust
 INNER JOIN Shops td
 ON td.ShopCode = cust.ShopCode
 INNER JOIN Zones tz
 ON tz.Id = td.SlsZone
 INNER JOIN Responses res
 ON res.SampleId = cust.SampleId
 INNER JOIN QstNodes qn
 ON qn.QuestionId = res.QstNodeId
GROUP BY tz.ZoneId, qn.QuestionId

UPDATE 1

The following illustrated on the demo has different records but that thought is the same.

answered Jan 24, 2013 at 15:37
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.