d'accord, donc la requête suivante peut probablement être effectuée sans sous-requête mais avec une jointure à la place. Je ferais confiance à l'optimiseur de requêtes pour cela, mais je n'en serais pas trop sûr.
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
Dans cette version, language_id 1 est utilisé comme alternative préférée, vous pourriez probablement ajouter plus de langues de la même manière. Utilisation de FIND_IN_SET
à la place, un critère de second ordre fonctionnerait également (FIND_IN_SET(cl.language_id,'1,2,3') DESC
ou quel que soit l'ordre que vous préférez).
Bien sûr, cette requête concerne actuellement un country_id fixe. Il pourrait être étendu de la même manière pour plusieurs pays avec une autre jointure :
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
une alternative aux sous-requêtes serait de joindre deux fois country_languages, et de sélectionner simplement la première qui n'est pas nulle (ce qui est probablement l'une des solutions les plus propres) :
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)
Si l'ID de langue 1 est votre langue de secours. Cela peut également être étendu pour fournir plusieurs langues de secours ...