MySQL столбец ALIAS в предложении WHERE - PullRequest
0 голосов
/ 22 ноября 2018

В этом запросе ниже у меня есть две таблицы, search_result и login_details.

SELECT fullname,
(SELECT MAX(login_time) FROM login_details WHERE reg_id=registration) as login_time 
FROM search_result WHERE hire_work=0;  

ПРИМЕЧАНИЕ: reg_id - это столбец в login_details, а регистрация - это столбец в search_result

. При выполнении вышеуказанного запроса я получаю полное имя ивремя последнего входа в систему всех пользователей в таблице search_result.

Теперь мое требование - выбрать всех пользователей вместе с временем последнего входа, которые не вошли в систему в течение последних 180 дней с сегодняшнего дня.Когда я добавляю условие WHERE, например login_time > '2018-05-22 18:09:00', отображается ошибка Неизвестный столбец login_time бла-бла .....

Запрос:

SELECT fullname,
(SELECT MAX(login_time) FROM login_details WHERE reg_id=registration) as login_time 
FROM search_result WHERE hire_work=0 AND login_time > '2018-05-22 18:09:00'; 

Пожалуйста, помогите мне найти точный запрос.Ответы будут оценены.Спасибо

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Причина, по которой вы не можете использовать псевдонимы (которые вы назначаете в части SELECT), заключается в том, что эта часть выполняется после части WHERE.Таким образом, эти псевдонимы недоступны, когда SQL-сервер выполняет часть WHERE.

Я бы не использовал запросы с HAVING без причины, поскольку они обычно дороже ресурсов для SQL-сервера.

Как и послеПользователям, которые НЕ входят в систему после указанной даты и времени, вам вообще не нужно находить MAX-время входа в систему, и простого левого соединения может быть достаточно:

SELECT
      sr.fullname
FROM
    search_result AS sr
    LEFT JOIN login_details AS ld ON (
            ld.reg_id = sr.registration
        AND ld.login_time > '2018-05-22 18:09:00'
    )
WHERE
        sr.hire_work = 0
    AND ld.login_time IS NULL
;

Если вам все еще нужно время последнего входа в систему для таких пользователей (это было бы до указанной вами даты и времени), вы можете добавить еще один подзапрос (как в исходном запросе) примерно так:

SELECT
      sr.fullname
    , (
        SELECT
            MAX(login_details.login_time)
        FROM
            login_details
        WHERE
            login_details.reg_id = sr.registration
    ) AS last_login_time
FROM
    search_result AS sr
    LEFT JOIN login_details AS ld ON (
            ld.reg_id = sr.registration
        AND ld.login_time > '2018-05-22 18:09:00'
    )
WHERE
        sr.hire_work = 0
    AND ld.login_time IS NULL
;
0 голосов
/ 22 ноября 2018

Ваш запрос не работает, потому что оператор WHERE выполняется перед оператором SELECT.Вы должны использовать оператор HAVING для фильтрации вычисляемых полей.Например:

SELECT fullname,
  (SELECT MAX(login_time)
   FROM login_details
   WHERE reg_id=registration) AS login_time
FROM search_result
WHERE hire_work=0
GROUP BY fullname
HAVING login_time < '2018-05-22 18:09:00'

Кроме того, подзапросы не являются хорошей практикой.Вы можете переписать этот запрос с помощью JOIN

SELECT search_result.fullname,
       MAX(login_details.login_time) AS login_time
FROM search_result
JOIN login_details ON login_details.reg_id=search_result.registration
WHERE search_result.hire_work=0
GROUP BY fullname
HAVING login_time < '2018-05-22 18:09:00'

И .. Вместо постоянной даты вы можете использовать следующее выражение: NOW() - INTERVAL 180 DAY.Например:

SELECT search_result.fullname,
       MAX(login_details.login_time) AS login_time
FROM search_result
JOIN login_details ON login_details.reg_id=search_result.registration
WHERE search_result.hire_work=0
GROUP BY fullname
HAVING login_time < NOW() - INTERVAL 180 DAY
...