2016-06-10 35 views
-1

问题陈述:我需要我的结果集来包含由于它们为NULL而不会自然返回的记录。当没有结果时添加行值 - MySQL

我打算在此放一些简化的代码,因为我的代码似乎太长了。

ScoresCompany_typeCompanyScore,在下面的Project_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 

一切工作正常,直到我申请COMPANY_TYPE不包括在结果的条件5个评分类别之一。发生这种情况时,我的结果集中不再有5行。

它显示是这样的:

Score Projects 
5  5 
3  6 
1  3 

我想它显示是这样的:

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

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


我试过Spencer7593下面的方法之一。我的一个简化查询现在看起来是这样的:

SELECT i.score AS Score,IFNULL(COUNT(*),0)作为Projects FROM(SELECT 5 AS得分 UNION ALL SELECT UNION ALL SELECT UNION ALL SELECT 2 UNION ALL SELECT 1)1 LEFT JOIN比分ON Scores.score = i.score GROUP BY分数 ORDER BY i.score DESC

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

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

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

+2

什么是要应用到数据的条件? – Lauthai

+3

请显示您的查询和您的表格结构。你很可能需要使用“外部连接”。 – sgeddes

+3

添加您的查询.. – Prashanth

回答

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 

注意,这将要求所有的扫描行,所以它可能表现不佳。 “技巧”是IF函数,当WHERE子句排除该行时,该函数返回NULL值代替project_id。)

如果我们确保project_id非NULL,那么我们可以使用更简洁的MySQL速记表达以实现等效的结果...

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

这适用因为MySQL返回1当比较结果为TRUE,并且otherwisee返回0或NULL。

+0

我实际上认为OP有5个类别,一个用于WHERE子句的修饰器,但希望这些行仍然返回,但是具有空值。这是一个完全不同于你的问题的解释......但是,根据目前的信息,无法判断谁是正确的。 –

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 
0

您发布的查询不会没有group by声明工作。但是,即使在那里,如果您没有那些公司类型的特定分数,也不会有效。

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

下面是使用conditional aggregation另一种选择:

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