没有结果时添加行值 - MySQL
Adding Row Values when there are no results - MySQL
问题陈述:我需要我的结果集包含自然不会return的记录,因为它们是 NULL。
由于我的代码似乎太长了,我将在此处放一些简化的代码。
Table Scores
有 Company_type
、Company
、Score
、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 行。 (分数 = 1-5)
我尝试了 Spencer7593 提供的以下方法之一。我的简化查询现在看起来像这样:
SELECT i.score AS Score
, IFNULL(count(*), 0) AS Projects
FROM (SELECT 5 AS 分数
联合所有
SELECT 4
联合所有
SELECT 3
联合所有
SELECT 2
联合所有
SELECT 1) 我
LEFT JOIN 得分 Scores.score = i.score
按分数分组
按 i.score 排序
并给出了以下结果,除了项目中带有 1 的行实际上应该是 0 之外,这是准确的,因为它们是由 "i" 派生的。没有得分为 5 或 2 的项目。
Score Projects
5 1
4 5
3 6
2 1
1 3
已解决!我只需要调整我的计数以专门查看项目计数 - count(project) 而不是 count(*)。这 return 达到了预期的结果。
如果您总是希望查询 return 5 行,Score
值为 5,4,3,2,1... 您将需要一个行源来提供这些 Score
值。
一种方法是对 return 这些固定值使用简单查询,例如
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
在这个例子中不一定是视图查询。但是确实需要一个行源,可以从中 return 编辑行。例如,您可以有一个简单的 table,其中包含这五行,以及这五个分数值。
这只是一般方法的示例方法。可以将您现有的查询修改为 return 您想要的行。但是如果没有看到查询、模式和示例数据,我们无法判断。
跟进
基于对问题的编辑,显示当前查询的示例。
如果我们保证Score
的五个值总是出现在Scores
table中,我们可以做条件聚合,这样写一个查询:
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
请注意,这将需要扫描所有行,因此它的性能可能不佳。 "trick" 是 IF 函数,当该行已被 WHERE 子句排除时,它 return 是一个 NULL 值代替 project_id。)
如果我们保证 project_id
是非 NULL,我们可以使用更简洁的 MySQL shorthand 表达式来获得等效的结果...
, IFNULL(SUM(s.company_type = :company_type),0) AS projects
这是有效的,因为当比较为 TRUE 时 MySQL returns 1
,否则 returns 0 或 NULL。
尝试这样的事情:
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
如果没有 group by
语句,您发布的查询将无法工作。但是,即使在那里,如果您没有针对该公司类型的那些特定分数,它也不会起作用。
一种选择是使用 outer join
。不过,这需要做更多的工作。
这是另一个使用 conditional aggregation
的选项:
select Score, sum(company_type=:company_type)
from Scores
group by Score
问题陈述:我需要我的结果集包含自然不会return的记录,因为它们是 NULL。
由于我的代码似乎太长了,我将在此处放一些简化的代码。
Table Scores
有 Company_type
、Company
、Score
、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 行。 (分数 = 1-5)
我尝试了 Spencer7593 提供的以下方法之一。我的简化查询现在看起来像这样:
SELECT i.score AS Score
, IFNULL(count(*), 0) AS Projects
FROM (SELECT 5 AS 分数
联合所有
SELECT 4
联合所有
SELECT 3
联合所有
SELECT 2
联合所有
SELECT 1) 我
LEFT JOIN 得分 Scores.score = i.score
按分数分组
按 i.score 排序
并给出了以下结果,除了项目中带有 1 的行实际上应该是 0 之外,这是准确的,因为它们是由 "i" 派生的。没有得分为 5 或 2 的项目。
Score Projects
5 1
4 5
3 6
2 1
1 3
已解决!我只需要调整我的计数以专门查看项目计数 - count(project) 而不是 count(*)。这 return 达到了预期的结果。
如果您总是希望查询 return 5 行,Score
值为 5,4,3,2,1... 您将需要一个行源来提供这些 Score
值。
一种方法是对 return 这些固定值使用简单查询,例如
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
在这个例子中不一定是视图查询。但是确实需要一个行源,可以从中 return 编辑行。例如,您可以有一个简单的 table,其中包含这五行,以及这五个分数值。
这只是一般方法的示例方法。可以将您现有的查询修改为 return 您想要的行。但是如果没有看到查询、模式和示例数据,我们无法判断。
跟进
基于对问题的编辑,显示当前查询的示例。
如果我们保证Score
的五个值总是出现在Scores
table中,我们可以做条件聚合,这样写一个查询:
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
请注意,这将需要扫描所有行,因此它的性能可能不佳。 "trick" 是 IF 函数,当该行已被 WHERE 子句排除时,它 return 是一个 NULL 值代替 project_id。)
如果我们保证 project_id
是非 NULL,我们可以使用更简洁的 MySQL shorthand 表达式来获得等效的结果...
, IFNULL(SUM(s.company_type = :company_type),0) AS projects
这是有效的,因为当比较为 TRUE 时 MySQL returns 1
,否则 returns 0 或 NULL。
尝试这样的事情:
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
如果没有 group by
语句,您发布的查询将无法工作。但是,即使在那里,如果您没有针对该公司类型的那些特定分数,它也不会起作用。
一种选择是使用 outer join
。不过,这需要做更多的工作。
这是另一个使用 conditional aggregation
的选项:
select Score, sum(company_type=:company_type)
from Scores
group by Score