Иногда я хочу присоединиться к записи, которую я могу легко определить как «отсортировать по тому и другому и выбрать первую запись».Интересно, какая здесь лучшая практика?
Например, в моей модели данных у меня есть службы и реализации.Сервис может иметь несколько реализаций.Реализации имеют номера версий;Может быть установлено ноль или более реализаций, и одна из них также может быть включена.Теперь я хочу выбрать «текущую реализацию» для каждой службы, используя следующие правила:
- Если ничего не установлено, то текущая реализация является самой последней.
- Если большечем один установлен, то текущим является либо тот, который включен, либо, если ничего не включено, снова самый последний.
Некоторые примеры:
Service Version Installed Enabled
======= ======= ========= =======
A 1 False False
A 2 False False <- current for service A because most recent
B 1 True False <- current for service B because installed
B 2 False False
C 1 True False
C 2 True False <- current for service C because most recent
C 3 False False among installed
D 1 True True <- current for service D because enabled
D 2 True False
IЯ подумал, что если я отсортирую по этим полям и выберу первую запись, это сработает.Т.е. я делаю что-то подобное:
SELECT s.service, <other service fields>, i.version, <other impl. fields>
FROM service s, implementation i
WHERE i.rowid == (
SELECT rowid
FROM implementation o
WHERE o.service == s.service
ORDER BY installed DESC, enabled DESC, version ASC)
Обновление. Это довольно специфично для SQLite, я думаю.Во-первых, rowid
- это внутренний идентификатор записи, который используется SQLite.Во-вторых, в SQLite выражение SELECT
в этом контексте возвращает одно значение.Я предполагаю, что его можно переписать в более общий SQL, например:
...
FROM service s, implementation i
WHERE i.service == s.service
AND i.version == (
SELECT version
FROM ...
ORDER BY ...
LIMIT 1)
Он работает здесь, но иногда нет rowid
или другого отдельного поля, которое может служить идентификатором.Есть ли другие способы получить такой же результат?Может быть, что-то более общее?(И для меня тоже есть что-то более конкретное, если оно специфично для SQLite:)