views:

59

answers:

3

I have a table with registered users, in which i save year as varchar values simply because i take just an year. I want to create pie chart with ages to show which users are more likely to register.

Query below gives me count of user ages which appear more than 5 times in Table to avoid small results. While these small results, below "having ount(userID)>5" i want to appear as others. What should i add to this query or possibly to re-design it. I can create silly solutions like to take all years that appear in initial query and then select all besides those year but there must be better and more creative way of writing this query.

So result will be something like that 1 10 1990 2 4 1980 3 10 others

select count(userID) ageCount,userBirthYear from Users
group by userBirthYear
having count(userID)>5
order by count(userID) desc

thanks

+2  A: 

Here's one way (assuming SQL2005 or later).

With Ages As
(
select count(userID) ageCount,userBirthYear 
from Users
group by userBirthYear
)

SELECT ageCount,userBirthYear FROM Ages WHERE ageCount>5
UNION ALL
SELECT sum(ageCount) ,'others' As userBirthYear FROM Ages WHERE ageCount<=5
Martin Smith
probably want less than or equal to 5 and not group on userBirthYear ...SELECT sum(ageCount) , 'Other' as userBirthYear FROM Ages WHERE ageCount<=5
Jeff O
@Jeff O - 'twas already fixed. Thanks!
Martin Smith
@Martin Smith, it works just you miss group by in last query or better way would be to replace userBirthYear with 'other' so i wouldn't need a group by at all
eugeneK
@eugeneK I meant to stick a NULL in there as you'll get type problems unionining with an int (unless you want to cast that column as a varchar?)
Martin Smith
@Martin Smith, yeah it is going to be varchar as i've said i want it 'others' and year is of varchar type
eugeneK
@eugeneK - Whoops that was your first sentence as well. Sorry!
Martin Smith
+1  A: 
select  count(userID) ageCount,userBirthYear from Users 
group   by userBirthYear 
having  count(userID)>5 
union
SELECT  SUM(agecount), 'Others' 
FROM    (select count(userID) ageCount,'Others' userBirthYear from Users 
     group  by userBirthYear 
     having count(userID)<5)TMP 
order by    count(userID) desc
Baaju
+3  A: 

Here's a regrouping solution (union-less) to avoid repeated IO.

The basic idea is you want every record to contribute to the result, so there should be no WHERE or HAVING clauses.

SELECT
  SUM(sub.ageCount) as ageCount,
  sub.userBirthYear
FROM
(
  SELECT Count(userId) ageCount,
    CASE WHEN COUNT(userID) > 5)
         THEN userBirthYear
         ELSE 'Other'
    END as userBirthYear
  FROM Users
  GROUP BY userBirthYear
) as sub
GROUP BY sub.userBirthYear
David B
+1 Yes I much prefer this one.
Martin Smith