PHP MYSQL Отображение результатов, включая NULL, с инструкциями Case

0

Я не могу заставить клиентов показать, нет ли данных в LEFT JOINED TABLE. Я думаю, что это связано с моими заявлениями CASE. Я пробовал все, что мог. Заранее спасибо за помощь. Текущие результаты показывают всех Клиентов с Onsite_Hours или Remote_Hours, если у них есть Часы. Проблема в том, что у меня есть клиенты, у которых есть Onsite_Hours или Remote_Hours, которые не отображаются, потому что нет записей в таблице часов.

$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){ 

Добавление примерных данных и ожидаемых результатов:

TABLE Клиенты

Id | Name   |  onsite_block_hrs  | remote_block_hrs
1  | Test1  |  3                  | 0
2  | Test2  |  0                  | 1
3  | Test3  |  0                  | 2
4  | Test4  | 3                   | 0
5  | Test5  | 0                   | 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 Не отображать, потому что нет на месте или удаленных часов

  • 1
    Пожалуйста, прочтите минимальный воспроизводимый пример .
  • 0
    Я прочитал статью. Извините, но не уверен, что вижу, что мне не хватает. Я включил единственный подходящий код и объяснил, чего я пытаюсь достичь.
Показать ещё 4 комментария
Теги:
left-join
case

3 ответа

1
Лучший ответ

Похоже, дата приходит из таблицы "Часы"; включая поле из правой таблицы LEFT JOIN в предложении WHERE, может эффективно превратить его в INNER JOIN, если значения NULL недопустимы; скорее всего, вам нужно перенести эти критерии в условие соединения, например:

...
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 на onsite_block_hours и remote_block_hrs должны были давать результаты суммирования всех часов (без учета диапазона дат полностью... если у них их не было).

  • 0
    Uueerdo, это решение сработало! Спасибо за помощь. Я не имею права голоса, но это правильное решение.
  • 0
    @kayakerpaul Вы можете нажать на значок галочки, чтобы показать, что это помогло больше всего, и наградить представителя.
Показать ещё 1 комментарий
0

От Уйердо. это окончательное решение:

Я переместил требования месяца и года к 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";
0

Я изменил ваш пример:

$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){ 

Чтобы вы получали клиентов с часами с текущей даты OR (а не И, как в вашем примере) с onsite_block_hrs/remote_block_hrs больше 0 - это то, что вы ищете, если я правильно понял вашу проблему.

  • 0
    Спасибо за помощь. Ваше решение будет показывать все записи часов, независимо от требований даты. Мне нужно, чтобы запись «Дата в часах» была в текущем месяце, И клиент должен иметь onsite_block_hrs ИЛИ remote_block_hrs, но если у них есть block_hrs и нет записей часов, они все равно отображаются.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню