SQL с ОБЪЕДИНЕНИЕМ, где столбец одной таблицы равен нулю, если глобальный WHERE не заполнен

#mysql #sql #join #select #left-join

#mysql #sql #Присоединиться #выберите #левое соединение

Вопрос:

прошло довольно много времени с тех пор, как мне приходилось писать SQL в последний раз. Я борюсь с выбором, и я надеялся, что вы можете указать, чего мне не хватает.

У меня довольно простая структура таблицы с 2 таблицами:

  1. Пользователи
    • user_id
    • Имя
  2. Оценки
    • user_id
    • оцените
    • оценка_date

Цель состоит в том, чтобы использовать дату начала и окончания, чтобы показать все оценки всех пользователей. Для пользователей, у которых нет оценки для этого конкретного временного диапазона, я хочу, чтобы SQL возвращал мне нулевое значение.

На самом деле задействовано еще несколько таблиц и столбцов, а также некоторые пользовательские роли, но в этом примере это не обязательно.

Я попытался настроить свой select следующим образом:

 SELECT a.id, a.name, b.estimate, b.estimation_date
FROM users a
LEFT OUTER JOIN estimates b on a.id = b.id
WHERE b.estimation_date BETWEEN $startdate AND $enddate OR b.estimation_date IS NULL
  

Пока пользователь вообще не произвел никакой оценки, результат — это то, что я хочу. Каждая строка является пользователем, один и тот же пользователь может встречаться несколько раз — по одному разу для каждой оценки в диапазоне дат — и пользователь без оценки имеет значение NULL в b.estimate и b.estimation_date.

Однако, как только пользователь произвел оценку, даже если она не входит в диапазон, пользователь больше не отображается в результате.

Каким было бы наилучшее решение для ввода начальной и конечной даты и получения всех пользователей и для каждого пользователя, у которого нет оценки внутри этого диапазона, получить значение NULL в этих столбцах?

Комментарии:

1. Не уверен, есть ли более эффективный способ сделать это в «одном запросе», но рассматривали ли вы возможность выполнения подзапроса к таблице оценок?

Ответ №1:

Поместите условие диапазона дат в on предложение:

 SELECT u.id, u.name, e.estimate, e.estimation_date
FROM users u LEFT OUTER JOIN
     estimates e
     ON u.id = e.id AND
        e.estimation_date >= $startdate AND
        (e.estimation_date <= $enddate OR e.estimation_date IS NULL)
  

Обратите внимание, что я также исправил псевдонимы таблиц, чтобы они не были бессмысленными буквами, а были сокращениями для имени таблицы.