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

MYSQL:如何在何处使用虚拟字段使用左连接查询?,mysql,Mysql,我必须找到使用年龄的用户。但是,age字段在myuser\u basic\u info表中不可用。我在user\u basic\u info表中有一个dob字段。我已经创建了虚拟年龄字段。但是,我返回了一个错误“where子句”中的未知列“age” 我的问题是: SELECT `users`.`nickname`, TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE()) AS `age` FROM `users` LEFT JOIN `

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

我的问题是:

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))
选择
`用户`.`昵称`,
TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE())作为'age`
来自`用户`
左连接`用户\基本\信息`
关于用户\基本\信息。用户\ id=用户。id
哪里
(`users`.`status`=1)和

((age>=22)或(age您不能在WHERE条件中直接使用age别名,因为您在条件中使用了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))
选择
`用户`.`昵称`,
TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE())作为'age`
来自`用户`
左连接`用户\基本\信息`
关于用户\基本\信息。用户\ id=用户。id
哪里
(`users`.`status`=1)

具有((TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE())>=22)或(TIMESTAMPDIFF(YEAR,user_basic_info.dob,CURDATE())出现此错误是因为计算时,
WHERE
子句中的
age
别名不可用。您的选项包括重复
WHERE
子句中的age表达式(丑陋)或执行子查询以使用别名(可能未执行).为了便于阅读,我可以这样做:

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; 

第二个
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))
选择
u、 “昵称”,
TIMESTAMPDIFF(年,用户基本信息dob,CURDATE())作为年龄
来自“用户”u
左连接`用户\基本\信息`
关于用户\基本\信息。用户\ id=u.id
哪里
(u.`地位'=1)
有

((年龄>=22&&age您应该尝试使用
Having
age
如下所示:

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
选择美国昵称,
TIMESTAMPDIFF(年,ubi.dob,CURDATE())作为年龄
来自用户作为u
作为ubi左加入用户\u基本\u信息
在ubi.user\u basic\u info.user\u id=u.users.id上
其中u.status=1
有

u、 age>=22或u.age由于sql执行行为,您可以在where子句中使用列的别名。请在此处回答。这就是为什么您可以在group by、having和order by子句中使用别名的原因。“当and执行时,having子句有什么意义?”因为
where
子句在应用
have
之前过滤结果集,所以存在性能差异。我不认为这与性能有关,更可能的是执行顺序在select之后,而where在它之前,所以年龄对HAVE可见,但对where不可见。对于提到我错过的选项,我投了赞成票d:使用重载的
HAVING
子句,该子句可以使用
SELECT
子句中的别名。“您测试过这个吗?我想‘如果省略GROUP BY子句,HAVING子句的行为类似于WHERE’,因此我认为使用WHERE子句测试年龄的问题也会起作用。”您测试过吗?您不能在
HAVING
子句中使用字段名,它只接受别名。