Okay, die folgende Abfrage kann wahrscheinlich ohne Unterabfrage, aber stattdessen mit einem Join durchgeführt werden. Ich würde darauf vertrauen, dass der Abfrageoptimierer dies tut, aber ich wäre mir nicht sicher.
SELECT l.name as language,
(SELECT cl.name
FROM country_languages cl
WHERE cl.country_id=[the wanted country id]
ORDER BY cl.language_id=l.id DESC,
cl.language_id=1 DESC
LIMIT 1) as country_name
FROM languages l
In dieser Version wird language_id 1 als bevorzugtes Fallback verwendet, Sie könnten wahrscheinlich weitere Sprachen auf ähnliche Weise hinzufügen. Mit FIND_IN_SET
stattdessen würde auch ein Kriterium zweiter Ordnung funktionieren (FIND_IN_SET(cl.language_id,'1,2,3') DESC
oder was auch immer Sie bevorzugen).
Natürlich ist diese Abfrage jetzt für eine feste country_id. Es könnte auf ähnliche Weise für mehrere Länder mit einem anderen Join erweitert werden:
SELECT l.name as language,
(SELECT cl.name
FROM country_languages cl
WHERE cl.country_id=c.id
ORDER BY cl.language_id=l.id DESC,
cl.language_id=1 DESC
LIMIT 1) as country_name
FROM countries c
JOIN languages l
Eine Alternative zu Unterabfragen wäre, die country_languages zweimal zu verbinden und einfach die erste auszuwählen, die nicht null ist (was wahrscheinlich eine der saubereren Lösungen ist):
SELECT l.name as language,
COALESCE(first.name, second.name) as country_name
FROM countries c
JOIN languages l
LEFT JOIN country_languages first ON
(first.country_id=c.id AND first.language_id=l.id)
LEFT JOIN country_languages second ON
(second.country_id=c.id AND second.language_id=1)
Wenn die Sprach-ID 1 Ihre Fallback-Sprache ist. Dies kann auch erweitert werden, um mehrere Fallback-Sprachen bereitzustellen ...