没有结果时添加行值 - MySQL

时间:2016-06-10 22:48:08

标签: mysql rows

问题陈述:我需要将结果集包含在自然返回的记录中,因为它们是NULL。

我要在这里放一些简化的代码,因为我的代码似乎太长了。

Scores包含Company_typeCompanyScoreProject_ID

Select Score, Count(Project_ID)
    FROM Scores
    WHERE company_type= :company_type
    GROUP BY Score

结果如下:

Score   Projects
5       95
4       94
3       215
2       51
1       155

一切正常,直到我将条件应用于不包含5个分数类别之一的结果的company_type。发生这种情况时,我的结果集中不再有5行。

它显示如下:

Score   Projects
5       5
3       6
1       3

我希望它显示如下:

Score   Projects
5       5
4       0
3       6
2       0
1       3

我需要结果总是显示5行。 (分数= 1-5)

我通过Spencer7593尝试了以下方法之一。我的简化查询现在看起来像这样:

选择i.score AS Score,IFNULL(count(*),0)AS Projects   FROM(SELECT 5 AS得分         UNION ALL         选择4         UNION ALL         选择3         UNION ALL         选择2         UNION ALL         选择1)我        LEFT JOIN得分ON Scores.score = i.score GROUP BY分数 订购依据i.score DESC

并给出以下结果,这是准确的,除了在Projects中带有1的行实际上应该是0,因为它们是由“i”派生的。没有得分为5或2的项目。

Score   Projects
5       1
4       5
3       6
2       1
1       3

解决!我只需要调整我的计数以专门查看项目计数 - 计数(项目)而不是计数(*)。这返回了预期的结果。

3 个答案:

答案 0 :(得分:0)

如果您始终希望查询返回5行,Score值为5,4,3,2,1 ......那么您需要一个提供Score {}的行源值。

一种方法是使用简单查询来返回那些固定值,例如

 SELECT 5 AS score
 UNION ALL SELECT 4
 UNION ALL SELECT 3
 UNION ALL SELECT 2
 UNION ALL SELECT 1

然后将该查询用作内联视图,并对当前查询的结果执行外部联接操作

 SELECT i.score                AS `Score`
      , IFNULL(q.projects,0)   AS `Projects`
   FROM ( SELECT 5 AS score
          UNION ALL SELECT 4
          UNION ALL SELECT 3
          UNION ALL SELECT 2
          UNION ALL SELECT 1
        ) i
   LEFT
   JOIN (
          -- the current query with "missing" Score rows goes here
          -- for completeness of this example, without the query 
          -- we emulate that result with a different query
          SELECT 5 AS score, 95 AS projects
          UNION ALL SELECT 3, 215
          UNION ALL SELECT 1, 155
        ) q
     ON q.score = i.score
  ORDER BY i.score DESC

在此示例中,它不必是视图查询。但是确实需要一个可以从中返回行的行源。例如,您可以拥有一个包含这五行的简单表格,其中包含这五个得分值。

这只是一般方法的示例方法。可以修改现有查询以返回所需的行。但是,如果没有查看查询,架构和示例数据,我们就无法说明。

<强>后续

根据对问题的编辑,显示当前查询的示例。

如果我们保证Score的五个值将始终显示在Scores表中,我们可以进行条件聚合,编写如下查询:

 SELECT s.score
      , COUNT(IF(s.company_type = :company_type,s.project_id,NULL)) AS projects
  FROM Scores s
 GROUP BY s.score
 ORDER BY s.score DESC

请注意,这将需要扫描所有行,因此可能无法执行。 &#34;技巧&#34;是IF函数,当WHERE子句排除了该行时,它返回一个NULL值来代替project_id。)

如果我们保证project_id非NULL,我们可以使用更简洁的MySQL速记表达式来实现相同的结果......

      , IFNULL(SUM(s.company_type = :company_type),0) AS projects

这是有效的,因为MySQL在比较为TRUE时返回1,否则返回0或NULL。

答案 1 :(得分:0)

尝试这样的事情:

select distinct score
from (
    select distinct score from scores
) s
left outer join (
    Select Score, Count(Project_ID) cnt
    FROM Scores 
    WHERE company_type= :company_type
) x
on s.score = x.score

答案 2 :(得分:0)

如果没有group by语句,您发布的查询将无效。但是,即使在那里,如果您没有该公司类型的特定分数,它也不会起作用。

一种选择是使用outer join。这需要更多的工作。

以下是使用conditional aggregation的另一个选项:

select Score, sum(company_type=:company_type) 
from Scores
group by Score