问题
I want to save the hassle of doing many querys for the following:
I have a table like this:
name, age
{
Mike, 7
Peter, 2
Mario, 1
Tony, 4
Mary, 2
Tom, 7
Jerry, 3
Nick, 2
Albert, 22
Steven, 7
}
And I want the following result:
Results(custom_text, num)
{
1 Year, 1
2 Year, 3
3 Year, 1
4 Year, 1
5 Year, 0
6 Year, 0
7 Year, 3
8 Year, 0
9 Year, 0
10 Year, 0
More than 10 Year, 1
}
I know how to do this but in 11 queries :( But how to simplify it?
EDIT:
Doing the following, I can obtain the non zero values, but I need the zeroes in the right places.
SELECT COUNT(*) AS AgeCount
FROM mytable
GROUP BY Age
How can I achieve this? Thanks for reading.
回答1:
you can use below query but it will not show the gaps
if you want gaps then the use Linoff's answer:
select t.txt, count(t.age) from
(select
case
when age<11 then concat(age ,' year')
else 'more than 10'
end txt, age
from your_table)t
group by t.txt
order by 1
SQL FIDDLE DEMO
回答2:
You can use left join
and a subquery to get what you want:
select coalesce(concat(ages.n, ' year'), 'More than 10 year') as custom_text,
count(*)
from (select 1 as n union all select 2 union all select 3 union all select 4 union all
select 5 union all select 6 union all select 7 union all select 8 union all
select 9 union all select 10 union all select null
) ages left join
tabla t
on (t.age = ages.n or ages.n is null and t.age > 10)
group by ages.n;
EDIT:
I think the following is a better way to do this query:
select (case when least(age, 11) = 11 then 'More than 10 year'
else concat(age, ' year')
end) as agegroup, count(name)
from (select 1 as age, NULL as name union all
select 2, NULL union all
select 3, NULL union all
select 4, NULL union all
select 5, NULL union all
select 6, NULL union all
select 7, NULL union all
select 8, NULL union all
select 9, NULL union all
select 10, NULL union all
select 11, NULL
union all
select age, name
from tabla t
) t
group by least(age, 11);
Basically, the query need a full outer join
and MySQL does not provide one. However, we can get the same result by adding in extra values for each age, so we know something is there. Then because name
is NULL
, the count(name)
will return 0
for those rows.
回答3:
Please try using this query for required output. SQL FIDDLE link http://www.sqlfiddle.com/#!9/4e52a/6
select coalesce(concat(ages.n, ' year'), 'More than 10 year') as custom_text,
count(t.age) from (select 1 as n union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9 union all select 10 union all select null ) ages left join tabla t
on (case when ages.n<11 then t.age = ages.n else t.age > 10 end)
group by ages.n;
来源:https://stackoverflow.com/questions/29336431/how-to-reduce-sql-queries-in-only-one-in-this-case