不同的MySQL版本为子查询中的LEFT JOIN和ORDER提供不同的结果

时间:2016-03-21 17:27:22

标签: mysql join subquery sql-order-by

自从迁移到MySQL 5.6后,我遇到了连接表的顺序问题。 这在MySQL 5.1中运行良好

我想为product_cat_pictures中的每个类别选择每个最后一张图片(最高ID)。在每次执行同一查询时,特定类别的图片顺序都不同。

SELECT c.id, repo.filename FROM product_cat_container AS c
LEFT JOIN (SELECT * FROM product_cat_pictures ORDER BY id DESC) AS p
  ON c.id = p.cat_id
LEFT JOIN picture_repository AS repo
  ON p.picture_id = repo.id
GROUP BY c.id
ORDER BY c.order


product_cat_container
---------------------
id  name  order


product_cat_pictures 
---------------------
id  cat_id  picture_id


picture_repository 
---------------------
id  filename

2 个答案:

答案 0 :(得分:0)

您使用了非ANSI SQL:

SELECT c.id, repo.filename FROM product_cat_container AS c
LEFT JOIN (SELECT * FROM product_cat_pictures ORDER BY id DESC) AS p
  ON c.id = p.cat_id
LEFT JOIN picture_repository AS repo
  ON p.picture_id = repo.id
GROUP BY c.id
ORDER BY c.order;

GROUP BY仅在c.id上,为repo.filename返回一个随机值(第一个可访问的值)。此行为是特定于MySQL版本的。

ANSI兼容查询没有此随机行为:

SELECT c.id, MIN(repo.filename) AS filename FROM product_cat_container AS c
LEFT JOIN (SELECT * FROM product_cat_pictures ORDER BY id DESC) AS p
  ON c.id = p.cat_id
LEFT JOIN picture_repository AS repo
  ON p.picture_id = repo.id
GROUP BY c.id
ORDER BY c.order;

此处MIN函数负责返回正确的结果(最小值)。

替代:

SELECT c.id, repo.filename FROM product_cat_container AS c
LEFT JOIN (SELECT * FROM product_cat_pictures ORDER BY id DESC) AS p
  ON c.id = p.cat_id
LEFT JOIN picture_repository AS repo
  ON p.picture_id = repo.id
GROUP BY c.id,repo.filename
ORDER BY c.order;

在这里,GROUP BY包含所有列,每个id可能产生超过1个结果,但同样是ANSI有效(即:100%定义)结果。

您必须选择使用哪种功能/风格来获得所需的结果。

答案 1 :(得分:0)

不要忘记添加外键和索引,以避免在表有数百万行时出现性能问题。

尝试:

SQL Fiddle demo

SELECT t.id,t.category,t.image
FROM YourTable t
ORDER BY CASE WHEN t.category = 'landscapes' then 1 else 0 end DESC,
         t.category