2016-03-21 2 views
0

MySQL 5.6への移行以降、結合されたテーブルの順序に問題があります。 これはMySQL 5.1でうまく動作しましたMySQLのバージョンが異なると、サブクエリのLEFT JOINとORDERが異なる結果になる

product_cat_picturesの各カテゴリの最後の1枚の画像(最高の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 
+0

チェック[GROUP BYの12.19.3 MySQLの取り扱い](http://dev.mysql.com/doc/refman/5.6/en/group-by -handling.html)。 – wchiquito

答えて

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はrepo.filenameのためにランダムな値(最初のアクセス可能値)を返すだけc.idです。この動作は、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%が定義されている)である結果。

希望する結果を得るために使用する機能/スタイルを選択する必要があります。

0

外部キーとインデックスを追加することを忘れないでください。テーブルに何百万行もあれば、パフォーマンス上の問題を避けることができます。

試してみてください。

SQL Fiddle demo

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) 
関連する問題