Ich habe eine Dokumententabelle (hier ist eine vereinfachte Version):
id | rev | Inhalt |
---|---|---|
1 | 1 | ... |
2 | 1 | ... |
1 | 2 | ... |
1 | 3 | ... |
Wie wähle ich eine Zeile pro ID aus und wähle nur die größte Umdrehung aus?
Basierend auf den oben genannten Daten sollte das Ergebnis zwei Zeilen enthalten: [1, 3, ...]
und [2, 1, ..]
;. Ich verwende MySQL.
Derzeit verwende ich eine Prüfung in einer while
-Schleife, um alte Versionen im Ergebnissatz zu erkennen und zu überschreiben. Aber ist das der einzige Weg, um Ergebnisse zu erzielen? Gibt es keine Lösung für SQL?
我更喜欢尽量少使用代码...
你可以使用
IN
来实现 试试这个:在我看来,这样更简单...更易读和维护。
乍一看...
你只需要在
GROUP BY
子句中使用MAX
聚合函数:事情从来都不是那么简单,是吗?
我刚刚注意到你还需要
content
列。这是SQL中一个非常常见的问题:根据某个分组标识符找到某一列中最大值对应的完整数据。在我的职业生涯中,我听到了很多这样的问题。实际上,在我目前的工作技术面试中,我就回答了这个问题之一。
这个问题实际上非常常见,以至于Stack Overflow社区创建了一个专门处理这类问题的标签:greatest-n-per-group。
基本上,你有两种方法来解决这个问题:
使用简单的
group-identifier, max-value-in-group
子查询进行连接在这种方法中,你首先在一个子查询中找到
group-identifier, max-value-in-group
(已经在上面解决了)。然后,你将你的表与子查询进行连接,使用group-identifier
和max-value-in-group
进行等值连接:使用自连接进行左连接,调整连接条件和过滤条件
在这种方法中,你将表与自身进行左连接。等值连接在
group-identifier
上。然后,有两个巧妙的步骤:NULL
(记住这是一个LEFT JOIN
)。然后,我们过滤连接结果,只显示右侧为NULL
的行。因此,你最终得到:
结论
这两种方法得到的结果完全相同。
如果你有两行具有相同的
group-identifier
和max-value-in-group
,那么这两种方法都会在结果中包含这两行。这两种方法都与SQL ANSI兼容,因此无论你使用的是哪种RDBMS,都可以使用这两种方法,不受其“风格”的影响。
这两种方法都非常高效,但是具体效果可能会有所不同(RDBMS、数据库结构、索引等)。因此,在选择其中一种方法时,请进行基准测试。并确保选择对你来说最有意义的方法。