MYSQL:如何在使用左连接查询的地方使用虚拟字段?

时间:2017-10-06 12:02:21

标签: mysql

我必须找到使用年龄的用户。但是,年龄字段在我的 user_basic_info 表中不可用。我在 user_basic_info 表中有一个 dob 字段。我已经创建了虚拟年龄字段。但是,我在“where子句”中返回了一个错误“未知列'年龄'”

我的查询:

SELECT
    `users`.`nickname`,
    TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE()) AS `age`
FROM `users`
LEFT JOIN `user_basic_info`
    ON user_basic_info.user_id = users.id
WHERE
    (`users`.`status`=1) AND
    ((age >= 22) OR (age <= 30))

4 个答案:

答案 0 :(得分:1)

您收到此错误是因为age子句在评估时WHERE子句中不可用。您的选项包括在WHERE子句中重复表达年龄(丑陋)或使用别名执行子查询(可能不是高性能)。为了便于阅读,我可以这样做:

SELECT
    nickname,
    age
FROM
(
    SELECT
        users.nickname,
        users.status,
        TIMESTAMPDIFF(YEAR, user_basic_info.dob, CURDATE()) AS age
    FROM users
    LEFT JOIN user_basic_info
        ON user_basic_info.user_id = users.id
) t
WHERE
    status = 1 AND age BETWEEN 22 AND 30;

如果您有表现意识,那么您可以在原始查询的WHERE子句中重复年龄表达式:

SELECT
    users.nickname,
    TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE()) AS age
FROM users
LEFT JOIN user_basic_info
    ON user_basic_info.user_id = users.id
WHERE
    user.status = 1 AND
    TIMESTAMPDIFF(YEAR, user_basic_info.dob, CURDATE()) BETWEEN 22 AND 30; 

答案 1 :(得分:1)

引用Where的第二个age子句应该转移到HAVING子句:

SELECT
    u.`nickname`,
    TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE()) AS age
FROM `users` u
LEFT JOIN `user_basic_info`
    ON user_basic_info.user_id = u.id
WHERE
    (u.`status`=1)
HAVING
    ((age >= 22 && age <= 30))

请注意,我已将Having编辑为更多作为'之间',否则他们并没有做太多。

(即13岁不超过22岁,但年龄小于30岁,因此也包括在内。一名99岁的人年龄超过22岁,因此也包括在内)

因此,将它们设为AND将检索22到30之间的所有人。

答案 2 :(得分:0)

您无法在 WHERE 条件中直接使用年龄别名,因为您已根据条件使用 HAVING 子句。

SELECT
    `users`.`nickname`,
    TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE()) AS `age`
FROM `users`
LEFT JOIN `user_basic_info`
    ON user_basic_info.user_id = users.id
WHERE
    (`users`.`status`=1)
  HAVING  ((TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE())>= 22) OR (TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE())<= 30))

答案 3 :(得分:0)

您应该尝试将Havingage一起使用,如下所示:

SELECT u.nickname,
TIMESTAMPDIFF(YEAR,ubi.dob,CURDATE()) AS age
FROM users as u
LEFT JOIN user_basic_info as ubi 
ON ubi.user_basic_info.user_id = u.users.id
WHERE u.status = 1 
HAVING
u.age >= 22 OR u.age <= 30