How to reduce SQL queries in only one in this case

拜拜、爱过 提交于 2019-12-06 15:11:54

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!