依存サブクエリを排除する方法を見つける必要があります。
複数の言語を使用できる記事の表があります。単純化されたテーブル構造は次のとおりです。
ID、タイトル、言語、translation_set_id
1 A en 0
2 B en 2
3 B_ru ru 2
4 C en 4
5 C_ru ru 4
6 D en 6
7 D_fr fr 6
記事に翻訳がない場合、translation_set_id は 0 であるか、基本翻訳の ID に設定されています。したがって、B は元の英語の記事であり、B_ru は記事のロシア語訳です。
すべてのロシア語の記事を返すことができるクエリが必要です。それらが存在しない場合は、元の言語の記事を返すことができます。だからそれは戻るでしょう。
1 A en 0
3 B_ru ru 2
5 C_ru ru 4
6 D en 6
これまでのところ、私はこれを持っています:
SELECT id, title, language, translation_set_id
FROM articles a
WHERE
a.translation_set_id = 0
OR (a.language = 'ru')
OR (a.id = a.translation_set_id AND
0 = (SELECT COUNT(ac.id)
FROM articles ac
WHERE ac.translation_set_id = a.translation_set_id
AND ac.language = 'ru')
)
ただし、これは行ごとにサブクエリを実行し、依存クエリを作成します。依存クエリを削除する方法はありますか?
更新: Neels のソリューションが機能しているようです、ありがとう!
しかし、複数言語のフォールバックに対するソリューションを一般化する方法があるかどうか疑問に思っていましたか? 最初にフランス語を取得してみてください。それが存在しない場合はロシア語を試してください。存在しない場合は、基本翻訳 (元の作成言語に応じて英語またはその他) を表示しますか?
UPDATE2: Neel のソリューションと DRapp のソリューションを使用して、更新された質問に必要なクエリを作成しました。ここで見つけることができますhttp://www.sqlfiddle.com/#!2/28ca8/18しかし、完全を期すために、ここでもクエリを省略します。
改訂データ:
CREATE TABLE articles (
id INT,
title VARCHAR(20),
language VARCHAR(20),
translation_set_id INT);
INSERT INTO articles values
(1,'A','en',0),
(2,'B','en',2),
(3,'B_ru','ru',2),
(4,'C','en',4),
(5,'C_ru','ru',4),
(6,'D','en',6),
(7,'D_fr','fr',6),
(8,'E_ru','ru', 0),
(9,'F_fr','fr', 0),
(10,'G_ru','ru', 10),
(11,'G_fr','fr', 10),
(12,'G_en','en', 10);
2 つの相関サブクエリを含む元のクエリ:
SELECT id, title, language, translation_set_id
FROM articles a
WHERE
a.translation_set_id = 0
OR (a.language = 'fr')
OR (a.language = 'ru' AND
0 = (SELECT COUNT(ac.id)
FROM articles ac
WHERE ac.translation_set_id = a.translation_set_id
AND ac.language = 'fr'))
OR (a.id = a.translation_set_id AND
0 = (SELECT COUNT(ac.id)
FROM articles ac
WHERE ac.translation_set_id = a.translation_set_id
AND (ac.language = 'fr' OR ac.language = 'ru'))
);
改訂されたクエリ:
SELECT a.*
FROM articles a
LEFT JOIN articles ac ON ac.translation_set_id = a.id
AND ac.language = 'fr'
LEFT JOIN articles ac2 ON ac2.translation_set_id = a.id
AND ac2.language = 'ru'
WHERE a.translation_set_id = 0
OR a.language = 'fr'
OR (a.language = 'ru' AND ac.id IS NULL)
OR (a.id = a.translation_set_id AND ac2.id IS NULL AND ac.id IS NULL);