我有一个如下所示的选择查询:
SELECT * FROM A
LEFT JOIN B ON B.x = A.y
LEFT JOIN C ...
WHERE ....
GROUP BY ...
ORDER BY ...;
Run Code Online (Sandbox Code Playgroud)
所有表都有id列和查询效果很好.结果有许多id列没有错误,驱动程序处理模糊的问题.但我需要在结果上有LIMIT,所以我用另一个选择查询包装它,如下所示:
SELECT * FROM (
SELECT * FROM A
LEFT JOIN B ON B.x = A.y
LEFT JOIN C ...
WHERE ....
GROUP BY ...
ORDER BY ...
) AS x WHERE 1 LIMIT 1000;
Run Code Online (Sandbox Code Playgroud)
现在我得到Duplicate column name 'id'错误!
PS:完整查询很复杂,我需要使用*(列表列名不可能),我不能在主查询中使用限制因为连接,按顺序分组等.
您收到错误的原因是由于别名AS X.但问题实际上是你使用过*,而不是列出你想要的字段.
在第一个查询中,SELECT *实际生成的字段如下:
A.id, A.name, A.description, B.id, B.name, B.date_started, C.id, C.name, C.isDeleted
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作,除非您尝试直接引用字段名称并且不使用它的别名.无论哪种方式,你的SQL引擎都不会有这个问题,不管你对结果集做什么,可能仍然有问题.
但是,当您将查询移动到子查询中并对结果进行别名时AS X,最终会得到:
X.id, X.name, X.description, X.id, X.name, X.date_started, X.id, X.name, X.isDeleted
Run Code Online (Sandbox Code Playgroud)
现在你可以看到为什么它在抱怨.您可以看到为什么它使用起来也很糟糕*,因为这种组合可能会工作一段时间,然后您将一个新字段添加到现有表中,这与另一个表相同,并且爆炸,您编写的每个查询这两个表现在都需要重写.
我通过自连接修复了它:
SELECT * FROM A
LEFT JOIN B ON B.x = A.y
LEFT JOIN C ...
JOIN (
SELECT id FROM (
SELECT id FROM A
WHERE ....
GROUP BY ...
ORDER BY ...
) AS A1 WHERE 1 LIMIT 1000
) AS A2 ON A2.id = A.id
WHERE 1
Run Code Online (Sandbox Code Playgroud)
MySQL 执行速度非常快。