PHP MYSQL显示结果,包括NULL和Case语句

PHP MYSQL显示结果,包括NULL和Case语句,php,mysql,left-join,case,Php,Mysql,Left Join,Case,当左联接表中没有数据时,我无法让客户端显示。我想这是因为我的案件陈述。我想尽了一切办法。提前谢谢你的帮助。 当前结果显示所有客户都有现场工作时间或远程工作时间(如果列出了工作时间)。问题是,我有一些客户机的现场工时或远程工时不显示,因为没有任何工时表条目 $sql = " SELECT Clients.Id, Clients.Rate, Clients.Name, Clients.onsite_block_hrs, Clients.remote_bloc

当左联接表中没有数据时,我无法让客户端显示。我想这是因为我的案件陈述。我想尽了一切办法。提前谢谢你的帮助。 当前结果显示所有客户都有现场工作时间或远程工作时间(如果列出了工作时间)。问题是,我有一些客户机的现场工时或远程工时不显示,因为没有任何工时表条目

$sql = "
SELECT 
    Clients.Id,
    Clients.Rate,
    Clients.Name,
    Clients.onsite_block_hrs,
    Clients.remote_block_hrs,
    Clients.Net,
    SUM(case WHEN Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS Onsite_Hours,
    SUM(case WHEN Clients.remote_block_hrs > 0 then Hours.Hours else 0 end) AS Remote_Hours,
    SUM(case WHEN DAY(Hours.Date) <= 15 && Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS First_Hours,
    SUM(case WHEN DAY(Hours.Date) >= 16 && Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS Second_Hours,
    Hours.Customer,
    Hours.Date
FROM
    Clients
LEFT JOIN
    Hours ON Clients.Id=Hours.Customer
WHERE
    MONTH(Date) = MONTH(CURRENT_DATE()) AND YEAR(Date) = YEAR(CURRENT_DATE()) AND (onsite_block_hrs != 0 || remote_block_hrs != 0)
    GROUP BY Id
    ORDER BY Name";
$result = $conn->query($sql);
    if ($result->num_rows > 0){ 
餐桌时间

Id | Customer | Date       | Hours
1  | 1        | 1-Jan-2018 | 2
2  | 2        | 2-Feb-2018 | 2
3  | 3        | 5-Feb-2018 | 1
4  | 5        | 3-Feb-2018 | 5
预期产出: 客户端1显示,因为它们有3个现场小时和2个小时,但不显示小时,因为它们不在当月 客户端2显示,因为它们在当月有1个远程和2个小时 客户端3显示相同的原因 客户端4显示,因为它们有3个现场小时,即使没有小时记录
客户端5不显示,因为没有现场或远程小时数

我修改了您的示例:

$sql = "
SELECT 
    Clients.Id,
    Clients.Rate,
    Clients.Name,
    Clients.onsite_block_hrs,
    Clients.remote_block_hrs,
    Clients.Net,
    SUM(case WHEN Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS Onsite_Hours,
    SUM(case WHEN Clients.remote_block_hrs > 0 then Hours.Hours else 0 end) AS Remote_Hours,
    SUM(case WHEN DAY(Hours.Date) <= 15 && Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS First_Hours,
    SUM(case WHEN DAY(Hours.Date) >= 16 && Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS Second_Hours,
    Hours.Customer,
    Hours.Date
FROM
    Clients
LEFT JOIN
    Hours ON Clients.Id=Hours.Customer
WHERE
    (MONTH(Date) = MONTH(CURRENT_DATE()) AND YEAR(Date) = YEAR(CURRENT_DATE())) OR (onsite_block_hrs != 0 || remote_block_hrs != 0)
    GROUP BY Id
    ORDER BY Name";
$result = $conn->query($sql);
    if ($result->num_rows > 0){ 

因此,您检索的客户端与当前日期的时差或不时差,如您的示例中的“现场阻止”时差/远程阻止时差大于0-如果我正确理解您的问题,这就是您要查找的内容。

看起来日期来自时数表;如果不允许空值,则在WHERE子句中包含左连接的右表中的字段可以有效地将其转换为内部连接;更有可能需要将这些条件移动到联接条件中,例如:

...
LEFT JOIN Hours ON Clients.Id=Hours.Customer
AND (MONTH(Date) = MONTH(CURRENT_DATE()) AND YEAR(Date) = YEAR(CURRENT_DATE()))
WHERE (onsite_block_hrs != 0 || remote_block_hrs != 0)
...
但是,OR部分可能会使实际解决方案不那么明显,并且应该会导致返回一些记录\


事实上,现场闭塞小时数和远程闭塞小时数的OR条件应产生所有小时数的总和,完全忽略日期范围……除非它们没有任何结果。

来自Uuerdo。这是最终的解决方案:

我将月份和年份要求移到了JOIN

$sql = "
SELECT 
Clients.Id,
Clients.Rate,
Clients.Name,
Clients.onsite_block_hrs,
Clients.remote_block_hrs,
Clients.Net,
SUM(case WHEN Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS Onsite_Hours,
SUM(case WHEN Clients.remote_block_hrs > 0 then Hours.Hours else 0 end) AS Remote_Hours,
SUM(case WHEN DAY(Hours.Date) <= 15 && Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS First_Hours,
SUM(case WHEN DAY(Hours.Date) >= 16 && Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS Second_Hours,
Hours.Customer,
Hours.Date
FROM
Clients
LEFT JOIN
Hours ON Clients.Id=Hours.Customer
AND (MONTH(Date) = MONTH(CURRENT_DATE()) AND YEAR(Date) = 
YEAR(CURRENT_DATE()))
WHERE
(onsite_block_hrs != 0 || remote_block_hrs != 0)
GROUP BY Id
ORDER BY Name";

请看,我已经看过这篇文章了。很抱歉,但我不确定我是否看到我遗漏了什么。我已经包含了唯一相关的代码,并解释了我试图完成的任务。好吧,让我们试试这个:编辑时,请查看编辑框下方的格式化版本。单击“已编辑”查看我是如何更正您的块代码表格式的,并在行尾列出格式2个空格。我们应该能够剪切、粘贴并运行一个。这包括将表格格式化为设置/输入表格的代码。以表格形式给出预期输出。理想情况下,作为表格式的代码,我们可以将其排序后的输出区分为我们的输出。更新的注释。了解left join on的作用。它返回行上的内部联接以及由null扩展的不匹配的左表行。因此,所有左表行始终显示在输出中。当左连接处于打开状态时,始终知道其关联的右连接是什么。而要求右表列为非null的where将删除左连接返回的行数大于内部连接返回的行数,因此应该使用内部连接来清除这些行。你在做那种毫无意义的左撇子加入这里。谢谢你的帮助。您的解决方案将显示所有小时条目,而不考虑日期要求。我需要工时记录上的日期在当月,客户必须有现场或远程的工时记录,但如果他们有工时记录且没有工时记录,则仍会显示。uuerdo,此解决方案有效!谢谢你的帮助。我没有排名可以投票,但这是正确的解决方案。@kayakerpaul您可以单击复选标记图标来显示这一点最有帮助&奖励代表。刚刚做的。谢谢你的提醒。
$sql = "
SELECT 
Clients.Id,
Clients.Rate,
Clients.Name,
Clients.onsite_block_hrs,
Clients.remote_block_hrs,
Clients.Net,
SUM(case WHEN Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS Onsite_Hours,
SUM(case WHEN Clients.remote_block_hrs > 0 then Hours.Hours else 0 end) AS Remote_Hours,
SUM(case WHEN DAY(Hours.Date) <= 15 && Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS First_Hours,
SUM(case WHEN DAY(Hours.Date) >= 16 && Clients.onsite_block_hrs > 0 then Hours.Hours else 0 end) AS Second_Hours,
Hours.Customer,
Hours.Date
FROM
Clients
LEFT JOIN
Hours ON Clients.Id=Hours.Customer
AND (MONTH(Date) = MONTH(CURRENT_DATE()) AND YEAR(Date) = 
YEAR(CURRENT_DATE()))
WHERE
(onsite_block_hrs != 0 || remote_block_hrs != 0)
GROUP BY Id
ORDER BY Name";