如何在UNION两张含同名列的表后按Customers表的Id排序?
解决UNION后按Customers表Id排序的问题
咱们先直接看可行的解决方案,再拆解为什么之前的写法会报错。
方法1:用子查询包裹UNION并给列起明确别名
这是最清晰、最推荐的方式,通过给Customers的Id列起一个唯一的别名,外层排序时直接引用这个别名就不会有问题:
SELECT * FROM ( -- 左连接结果,给Customers的Id起别名cust_id SELECT c.Id AS cust_id, c.Name, o.Id AS order_id, o.CustomerId AS order_cust_id FROM customers c LEFT JOIN orders o ON c.Id = o.CustomerId UNION -- 右连接结果,保持相同的列别名 SELECT c.Id AS cust_id, c.Name, o.Id AS order_id, o.CustomerId AS order_cust_id FROM customers c RIGHT JOIN orders o ON c.Id = o.CustomerId ) AS combined_results -- 直接用别名排序 ORDER BY cust_id;
如果不想重命名所有列,至少给Customers的Id起个唯一别名就行:
SELECT * FROM ( SELECT c.Id AS cust_id, c.Name, o.Id, o.CustomerId FROM customers c LEFT JOIN orders o ON c.Id = o.CustomerId UNION SELECT c.Id AS cust_id, c.Name, o.Id, o.CustomerId FROM customers c RIGHT JOIN orders o ON c.Id = o.CustomerId ) AS union_result ORDER BY cust_id;
方法2:用列的位置排序(不推荐)
如果你不想改子查询里的列名,也可以用结果集中列的位置来排序——Customers的Id是第一列,所以用ORDER BY 1:
SELECT * FROM customers c LEFT JOIN orders o ON c.Id = o.CustomerId UNION SELECT * FROM customers c RIGHT JOIN orders o ON c.Id = o.CustomerId ORDER BY 1;
⚠️ 但这种方式可读性差,如果后续调整SELECT的列顺序,排序逻辑会出错,所以尽量不用。
为什么之前的写法会报错?
咱们来拆解两个错误的原因:
Error Code: 1250:全局的ORDER BY是在UNION合并后的结果集上执行的,这时候子查询里的表别名c已经不在外层的作用域里了,MySQL找不到这个表,自然没法引用c.id。Error Code: 1052:合并后的结果集里有两个Id列(一个来自Customers,一个来自Orders),MySQL不知道你要按哪个Id排序,所以报“列名歧义”。
内容的提问来源于stack exchange,提问作者Chris Ma
相关产品推荐
相关产品推荐

