首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不同的MySQL版本对子查询中的左连接和顺序提供了不同的结果

问不同的MySQL版本对子查询中的左连接和顺序提供了不同的结果
EN

Stack Overflow用户
提问于 2016-03-22 01:27:22
回答 2查看 74关注 0票数 0

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

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

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

发布于 2016-03-22 02:47:32

您使用了非ANSI SQL:

代码语言:javascript
复制
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的查询没有这种随机行为:

代码语言:javascript
复制
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函数负责返回正确的结果(最小值)。

替代方案:

代码语言:javascript
复制
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%定义的)结果。

您必须选择使用哪种函数/样式来获得您想要的结果。

票数 0
EN

Stack Overflow用户

发布于 2016-03-22 22:02:08

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

尝试:

SQL Fiddle demo

代码语言:javascript
复制
mysql> DROP TABLES IF EXISTS `product_cat_container`;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLES IF EXISTS `product_cat_pictures`;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLES IF EXISTS `picture_repository`;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `product_cat_container` (
    ->     `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ->     `name` VARCHAR(25),
    ->     `order` INT UNSIGNED
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE IF NOT EXISTS `product_cat_pictures` (
    ->     `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ->     `cat_id` INT UNSIGNED,
    ->     `picture_id` INT UNSIGNED
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `picture_repository` (
    ->     `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ->     `filename` VARCHAR(25)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO `product_cat_container`
    ->     (`name`, `order`)
    -> VALUES
    ->     ('AAA', 1), ('BBB', 2), ('CCC', 3), ('DDD', 4);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> INSERT INTO `picture_repository`
    ->     (`filename`)
    -> VALUES
    ->     ('AAA'), ('BBB'), ('CCC'), ('DDD'), ('EEE');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> INSERT INTO `product_cat_pictures`
    ->     (`cat_id`, `picture_id`)
    -> VALUES
    ->     (1, 4), (1, 2), (1, 1), (2, 3), (3, 5), (3, 4);
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SELECT
    ->   `c`.`id`,
    ->   `repo`.`filename`
    -> FROM
    ->   `product_cat_container` `c`
    ->     LEFT JOIN (
    ->                 SELECT
    ->                   `p`.`cat_id`,
    ->                   `p`.`picture_id`
    ->                 FROM
    ->                   `product_cat_pictures` `p`
    ->                     INNER JOIN (
    ->                                 SELECT
    ->                                   MAX(`id`) `id`
    ->                                 FROM
    ->                                   `product_cat_pictures`
    ->                                 GROUP BY
    ->                                   `cat_id`
    ->                                 ) `d` ON `p`.`id` = `d`.`id`
    ->               ) `p` ON `c`.`id` = `p`.`cat_id`
    ->     LEFT JOIN `picture_repository` `repo` ON `p`.`picture_id` = `repo`.`id`
    -> ORDER BY
    ->   `c`.`order`;
+----+----------+
| id | filename |
+----+----------+
|  1 | AAA      |
|  2 | CCC      |
|  3 | DDD      |
|  4 | NULL     |
+----+----------+
4 rows in set (0.00 sec)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36137823

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档