有时我想加入一条记录,我可以轻松识别为“按此排序并选择第一条记录”。我想知道这里的最佳做法。SQL以自定义排序顺序加入第一条记录
例如在我的数据模型中我有服务和实现。服务可能有多个实现。实现有版本号;可以安装零个或多个实现,并且还可以启用其中的一个。现在我想使用以下规则为每个服务选择“当前实现”:
- 如果没有安装任何内容,那么当前的实现是最近的一个。
- 如果安装了多个安装,那么当前是启用的或者如果没有启用,则再次是最新的。
一些例子:
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
我想,如果我有点被这些田里挖第一个记录,它会做的伎俩。即我这样做:
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的特定:)
是否有某些原因您不使用INNER JOIN? –
你确定这可以吗?因为子查询可能会返回多于一行,并且您在rowid上使用了相等运算符。 – NullUserException
我可以,但我不明白它会在这里有什么不同。一个内部联接会给我所有匹配的实现,这可以作为一个起点,但是我想选择一个以任何排序顺序排在第一位的实现:) –