在这种情况下如何减少 SQL 个查询
How to reduce SQL queries in only one in this case
我想省去为以下问题做很多查询的麻烦:
我有一个 table 这样的:
name, age
{
Mike, 7
Peter, 2
Mario, 1
Tony, 4
Mary, 2
Tom, 7
Jerry, 3
Nick, 2
Albert, 22
Steven, 7
}
我想要以下结果:
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
}
我知道该怎么做,但是在 11 个查询中:( 但是如何简化它呢?
编辑:
执行以下操作,我可以获得非零值,但我需要在正确的位置使用零。
SELECT COUNT(*) AS AgeCount
FROM mytable
GROUP BY Age
我怎样才能做到这一点?
感谢阅读。
您可以使用 left join
和子查询来获取您想要的内容:
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;
编辑:
我认为以下是执行此查询的更好方法:
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);
基本上,查询需要一个full outer join
而MySQL没有提供。但是,我们可以通过为每个年龄添加额外的值来获得相同的结果,因此我们知道那里有一些东西。然后因为 name
是 NULL
,count(name)
将 return 0
对于这些行。
你可以使用下面的查询,但它 will not show the gaps
如果你想要间隙然后使用 :
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 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;
我想省去为以下问题做很多查询的麻烦:
我有一个 table 这样的:
name, age
{
Mike, 7
Peter, 2
Mario, 1
Tony, 4
Mary, 2
Tom, 7
Jerry, 3
Nick, 2
Albert, 22
Steven, 7
}
我想要以下结果:
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
}
我知道该怎么做,但是在 11 个查询中:( 但是如何简化它呢?
编辑:
执行以下操作,我可以获得非零值,但我需要在正确的位置使用零。
SELECT COUNT(*) AS AgeCount
FROM mytable
GROUP BY Age
我怎样才能做到这一点? 感谢阅读。
您可以使用 left join
和子查询来获取您想要的内容:
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;
编辑:
我认为以下是执行此查询的更好方法:
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);
基本上,查询需要一个full outer join
而MySQL没有提供。但是,我们可以通过为每个年龄添加额外的值来获得相同的结果,因此我们知道那里有一些东西。然后因为 name
是 NULL
,count(name)
将 return 0
对于这些行。
你可以使用下面的查询,但它 will not show the gaps
如果你想要间隙然后使用
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 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;