WHERE子句中的MySQL列ALIAS

时间:2018-11-22 14:13:51

标签: mysql sql where-clause

在下面的查询中,我有两个表search_resultlogin_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 :(得分:4)

您的查询不起作用,因为WHERE语句在SELECT语句之前执行。 您应该使用HAVING statement来过滤计算字段。例如:

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

答案 1 :(得分:1)

之所以不能使用别名(在SELECT部分​​中分配),是因为该部分在WHERE部分之后执行。因此,当SQL Server执行WHERE部分时,这些别名不可用。

我不会无缘无故地使用带有HAVING的查询,因为对于SQL Server,它们通常会占用更多资源。

就像您追随在指定日期时间后未登录的用户一样,您根本不需要查找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
;