这是问题所在。在运行该类型的任何查询
时SELECT field1
FROM table1
WHERE EXISTS (SELECT table2.field2, table3.field3, table3.field4
FROM table2 LEFT JOIN table3 ON table3.field3 = table2.field2
AND table3.field4 = table1.field1
WHERE "some condition");
我收到此错误:
Unknown column 'table1.field1' in 'on clause'
另一方面,此查询
SELECT field1
FROM table1
WHERE EXISTS (SELECT table2.field2, table3.field3, table3.field4
FROM table2 LEFT JOIN table3 ON table3.field3 = table2.field2
WHERE "some condition"
AND table3.field4 = table1.field1);
工作正常。
可能有其他选择,例如,它可以是内部联接而不是外部联接,否定子查询检查(不存在),其中不需要子句且字段列表可以不同。唯一关键的部分是EXISTS子查询,并在JOIN处于ON条件下引用table1.field1。
我在多个MySQL和MariaDB服务器上尝试了相同的结果!还尝试在线上找到完全相同问题,因此在SO上没有成功。
根据其中一条评论中的建议,我用一个真实的例子修改了这个问题。
表格:
CREATE TABLE `sessions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`browser` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
)
CREATE TABLE `browsers` (
`id` int(11) NOT NULL DEFAULT '0',
`browser` varchar(255) DEFAULT NULL
)
要获取使用所有浏览器的所有用户,我运行此查询
select distinct user_id
from sessions as t1
where not exists (select t2.id, browsers.id
from sessions as t2 LEFT JOIN browsers ON t2.browser = browsers.browser
AND t2.user_id = t1.user_id
where browsers.id IS NULL);
我收到的错误消息:
Error Code : 1054
Unknown column 't1.user_id' in 'on clause'
当然,我需要的输出是选择带有用户列表的查询结果集。
我知道如何重写此特定任务的查询,因此这不是问题。问题在于,使用此模式运行查询可以执行任何其他任务,因为它看起来非常合乎逻辑并且是很好的SQL。
我的问题是我在做错什么,如果那是一个错误,我如何避免保持相同的查询结构。
答案 0 :(得分:1)
我认为您遇到了bug#96946,MySQL在JOIN ON子句中不允许外部引用。
如果我没记错的话,这是对双重嵌套的NOT EXISTS查询的重写,我认为该语句实际上将在MySQL中被接受:
SELECT DISTINCT user_id
FROM sessions AS s1
WHERE NOT EXISTS (SELECT *
FROM browsers AS b
WHERE NOT EXISTS (SELECT *
FROM sessions s2
WHERE s1.user_id = s2.user_id AND
s2.browser = b.browser
)
);