Reputation: 302
First off: total SQL newbie here. I unfortunately had this thrust on me on a deadline. :/ My apologies if this is a dumb question.
So I have a DB with a view that has various columns. It has two columns I'm interested in: UserID and Age.
The view lists all reports for a user.
We I need to do is create a new table/view from the existing view that lists each unique user, and then breaks down their total documents into various age groups. So the columns would look something like:
User || # rprts <14 days || # rprts 14-17 days || # rprts 18-28 days || # rprts 29-44 days || # rprts 45+ days
I know I can get the set of all the users I want with:
SELECT DISTINCT [UserID] FROM [DB].[dbo].[DB_View]
And I can run the following and get one row of what I want for the new table/view by hardcoding a UserID #:
SELECT DISTINCT
[UserID],
(SELECT COUNT(*) FROM [DB].[dbo].[DB_View] WHERE (Age < 14) AND UserID = '9999') AS "Less Than 14 Days",
(SELECT COUNT(*) FROM [DB].[dbo].[DB_View] WHERE (Age BETWEEN 14 AND 17) AND UserID = '9999') AS "14 to 17 Days",
(SELECT COUNT(*) FROM [DB].[dbo].[DB_View] WHERE (Age BETWEEN 18 AND 28) AND UserID = '9999') AS "18 to 28 Days",
(SELECT COUNT(*) FROM [DB].[dbo].[DB_View] WHERE (Age BETWEEN 29 AND 44) AND UserID = '9999') AS "29 to 44 Days",
(SELECT COUNT(*) FROM [DB].[dbo].[DB_View] WHERE (Age >= 45) AND UserID = '9999') AS "Over 45 Days"
FROM [DB].[dbo].[DB_View]
WHERE UserID = '9999'
The result set of users is about ~600 rows, and the view usually has about 6,000-15,000 rows. My initial thought was just get my result set of users, then store each user to a parameter, and then pass that into the query where I've hardcoded a User ID. Sadly, I can't even figure out the SQL to do that. (And I'm guessing there's a much more efficient way to do this if you know your SQL....) I've seen stuff on using cursors and stuff, but I don't really understand it that well.
Any ideas?
Upvotes: 0
Views: 331
Reputation: 1269513
You can do this with a simple group by, with the CASE statement for conditional sums by age:
SELECT [UserID],
SUM(case when Age < 14 then 1 else 0 end) AS "Less Than 14 Days",
SUM(case when Age BETWEEN 14 AND 17 then 1 else 0 end) as "14 to 17 Days",
SUM(case when Age BETWEEN 18 AND 28 then 1 else 0 end) as "18 to 28 Days",
SUM(case when Age BETWEEN 29 AND 44 then 1 else 0 end) as "29 AND 44 Days",
SUM(case when Age BETWEEN 29 AND 44 then 1 else 0 end) as "29 AND 44 Days",
SUM(case when Age >= 45 then 1 else 0 end) as "Over 45 Days"
from [DB].[dbo].[DB_View]
where UserID = '9999'
group by userID
Upvotes: 0
Reputation: 116448
If I'm understanding you right:
SELECT [UserID],
COUNT(CASE WHEN Age < 14 THEN 1 ELSE NULL END) AS [Less Than 14 Days],
COUNT(CASE WHEN Age BETWEEN 14 AND 17 THEN 1 ELSE NULL END) AS [14 to 17 Days],
COUNT(CASE WHEN Age BETWEEN 18 AND 28 THEN 1 ELSE NULL END) AS [18 to 28 Days],
COUNT(CASE WHEN Age BETWEEN 29 AND 44 THEN 1 ELSE NULL END) AS [29 to 44 Days],
COUNT(CASE WHEN Age >= 45 THEN 1 ELSE NULL END) AS [Over 45 Days]
FROM [DB].[dbo].[DB_View]
GROUP BY [UserID]
Upvotes: 3