This question searches for an answer in pure sql (no db-server specific code)
-edit-
Due comments/answers:
"pure sql" – SQL92/99 because this works on all servers. I do not only use this code on mysql, this was just the first one I tried. I have to support Microsoft SQL Server (2000!), h2, PostGRE SQL and MySQL Server but the code should work on others too (db server independent). I'm sorry if "pure sql" was not detailed enough. Next time I'll specify requirement of the revision of SQL (3/4, 92/99)
I have to be backwards compatible.
And this is why I did not specify a db server. This was on purpose.
-end-of-edit-
I try to get all values from a table with given limits.
The data i have for the query is: possible locales and a max_priority
this is the table to work with
SELECT * FROM i18n
.
id|featureName|locale |priority|text
--+-----------+-----------+--------+----
1| type | en| 1|father
2| type | de| 2|Vater
3| type | de_AT| 3|Papa
4| type | de_AT_Wien| 4|Oida
5| firstName | en| 1|first name
6| firstName | de| 2|Vorname
7| lastName | en| 1|last name
8| lastName | de| 2|Nachname
9| lastName | fr| 2|nom de famille
10| firstName | fr| 2|prénom
so for example i have en
, de
, de_AT
and a max_priority of 3 (which is the priority of de_AT
)
i expect this as result: (the order of these results are not important!)
id|featureName|locale |priority|text
--+-----------+-----------+--------+----
3| type | de_AT| 3|Papa
6| firstName | de| 2|Vorname
8| lastName | de| 2|Nachname
i tried to solve this with an left outer join
this is the best result i was able to get:
SELECT DISTINCT nls1.*
FROM i18n nls1
LEFT OUTER JOIN i18n nls2
ON (
nls1.featureName = nls2.featureName
and nls1.priority > nls2.priority
)
WHERE nls2.priority<=3
AND (nls1.locale='en' OR nls1.locale='de' OR nls1.locale='de_AT')
GROUP BY featureName
ORDER BY featureName, priority DESC
but this selects those rows:
id|featureName|locale |priority|text
--+-----------+-----------+--------+----
2| type | de| 2|Vater
6| firstName | de| 2|Vorname
8| lastName | de| 2|Nachname
another try was
SELECT nls2.*
FROM i18n nls2
JOIN (SELECT Max(priority) max_priority,
featurename,
priority
FROM i18n nls
WHERE ( locale = 'en'
OR locale = 'de'
OR locale = 'de_AT' )
AND priority <= 3
GROUP BY featurename) nls3
ON nls3.priority = nls2.priority
AND nls3.featurename = nls2.featurename
but this one only returns the en version…
id|featureName|locale |priority|text
--+-----------+-----------+--------+----
1| type | en| 1|father
5| firstName | en| 1|first name
7| lastName | en| 1|last name
NOTE: i'll update the question depending on the answers.
The main problem seems that i need a group by
an column
but the group also needs a order by
?
Best Answer
Without window functions, the query will be complicated. One way to solve the problem in MySQL:
Also note that the above query will fail it is in SQL Server (which uses
TOP
, notLIMIT
) and possibly fail in other DBMS as well.