我有以下查询(通过PHP执行)。如果结果为NULL且未显示,如何显示ZERO。
select count(schicht) as front_lcfruh,
kw,
datum
from dienstplan
left join codes on dienstplan.schicht = codes.lcfruh
left join personal on personal.perso_id = dienstplan.perso_id
where codes.lcfruh != ''
and personal.status = 'rezeption'
and dienstplan.kw = '$kw'
group by dienstplan.datum
答案 0 :(得分:0)
我不完全确定我理解这个问题,但我认为你想要这个:
select count(codes.lcfruh) as front_lcfruh,
dienstplan.kw,
dienstplan.datum
from dienstplan
left join codes on dienstplan.schicht = codes.lcfruh and codes.lcfruh <> ''
left join personal on personal.perso_id = dienstplan.perso_id
and personal.status = 'rezeption'
and dienstplan.kw = $kw
group by dienstplan.datum, dienstplan.kw
如果schicht
来自dienstplan
,那么总会有一行(因为那是驱动表)。如果我理解正确,如果找不到匹配的行,则需要0
。因此,您需要计算已加入表。
编辑:
条件where codes.lcfruh != ''
将外连接转回到内连接,因为任何“外”行都将lcfruh设为NULL,任何与NULL的比较都会产生“未知”,因此从最终结果中删除行。如果要排除codes
表中lcfruh
空字符串的行,则需要将该条件移动到JOIN子句中(参见上文)。
还有两件事:习惯于在具有多个表的查询中为列添加前缀。这避免了歧义,并使查询更加稳定。您还应该理解数字文字和字符串文字之间的区别1
是一个数字'1'
是一个字符串。在预期数字的情况下使用字符串文字是一个坏习惯。 MySQL非常宽容,因为它总是尝试“以某种方式”工作,但如果你曾经使用其他DBMS,你可能会得到你不理解的错误。
此外,您对group by
的使用是错误的,并会导致返回“随机”值。请参阅这些博客文章以了解原因:
每个其他DBMS都会以现在的方式拒绝您的查询(如果您打开更符合ANSI标准的模式,MySQL也会这样做)
答案 1 :(得分:0)
如果没有匹配的行,那么MySQL将返回空集(这里我已经随机定义了字段,只是为了运行查询):
mysql> CREATE TABLE dienstplan (kw varchar(10), datum integer, schicht integer, perso_id integer);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE codes (lcfruh varchar(2));
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE personal (perso_id integer, status varchar(5));
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> select count(schicht) as front_lcfruh,
-> kw,
-> datum
-> from dienstplan
-> left join codes on dienstplan.schicht = codes.lcfruh
-> left join personal on personal.perso_id = dienstplan.perso_id
-> where codes.lcfruh != ''
-> and personal.status = 'rezeption'
-> and dienstplan.kw = '$kw'
-> group by dienstplan.datum;
Empty set (0.00 sec)
您可以检查查询返回的行数。在这种情况下,你将得到零。
所以你可以修改你的代码(伪代码):
$exec = $db->execute($query);
if ($exec->error() !== false) {
// Handle errors. Possibly quit or raise an exception.
}
if (0 == $exec->count())
{
// No rows. We return a default tuple
$tuple = array(
'front_lcfruh' => 0,
'kw' => $kw,
'datum' => null
);
handleTuple($tuple);
} else {
while($tuple = $exec->fetch()) {
handleTuple($tuple);
}
}
其中handleTuple()
是格式化或操纵返回行的函数。
答案 2 :(得分:0)
SELECT dp.datum
, MIN(kw) -- To avoid adding it to GROUP BY clause
, count(schicht) AS front_lcfruh
FROM dienstplan dp
LEFT JOIN codes co ON dp.schicht = co.lcfruh
LEFT JOIN personal pe ON pe.perso_id = dp.perso_id
WHERE dp.kw = '$kw'
AND COALESCE(co.lcfruh, 'X') <> '' -- Handle NULLs, too
AND COALESCE(pe.status , 'rezeption' ) = 'rezeption' -- Handle NULLs, too
GROUP BY dp.datum
;
答案 3 :(得分:0)
COUNT()永远不会返回NULL。
Lorenzo说(见评论)我应该提供帮助SO社区的参考。基于这些反馈,我在下面编辑了我的答案。
答案 4 :(得分:0)
select COALESCE(count(schicht),0) as front_lcfruh,kw,datum
from dienstplan
left join codes on dienstplan.schicht = codes.lcfruh
left join personal on personal.perso_id = dienstplan.perso_id
where codes.lcfruh != ''
and personal.status = 'rezeption'
and dienstplan.kw = '$kw'
group by dienstplan.datum
只需替换
count(schicht)
与
COALESCE(count(schicht),0)