【问题标题】:How to reduce SQL queries in only one in this case在这种情况下如何仅减少一次 SQL 查询
【发布时间】:2015-03-29 23:57:55
【问题描述】:

我想省去对以下内容进行多次查询的麻烦:

我有一张这样的桌子:

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

我怎样才能做到这一点? 感谢阅读。

【问题讨论】:

  • 您将三个问题混为一谈。第一个涉及简单的聚合——我想你知道怎么做。第二个是简单的case语句;我想你知道该怎么做。第三个问题涉及对缺失结果的处理。这是一个显示问题。一般来说,数据显示的问题最好在应用程序级代码(例如Php)中处理
  • 我想我可以用PHP添加自定义字符串,但是,如何获取第二列?

标签: mysql sql join group-by having


【解决方案1】:

您可以使用下面的查询,但如果您想要空白,请使用 will not show the gaps,然后使用 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

【讨论】:

  • 我有一个小问题,如果我有一个现有查询,并且我想将您的代码应用于我现有查询输出的表,我必须更改什么?实际上我有那个查询的FROMWHERE 块,我解释得好吗?
  • 这可能取决于您的查询,但是将您的查询包装到括号中而不是 your_table 可能会解决它
  • 我将在 StackOverflow 上创建另一个问题,并将链接粘贴到此处,因为是相关问题。
  • 你知道的。如果它与此问题不同,并且此问题中的答案无法解决,则发布它
【解决方案2】:

您可以使用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 不提供。但是,我们可以通过为每个年龄添加额外的值来获得相同的结果,所以我们知道那里有一些东西。然后因为nameNULLcount(name) 将为这些行返回0

【讨论】:

    【解决方案3】:

    请尝试使用此查询获取所需的输出。 SQL FIDDLE链接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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-25
      • 2011-01-09
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 2014-06-26
      • 2011-10-12
      • 1970-01-01
      相关资源
      最近更新 更多