Ich habe eine Dokumententabelle (hier eine vereinfachte Version):
id | Weiterleiten | Inhalt |
---|---|---|
1 | 1 | ... |
2 | 1 | ... |
1 | 2 | ... |
1 | 3 | ... |
Wie wähle ich eine Zeile für jede ID aus und wähle nur die größte Rev aus?
Basierend auf den oben genannten Daten sollte das Ergebnis zwei Zeilen enthalten: [1, 3, ...]
和 [2, 1, ..]
. Ich verwende MySQL.
Derzeit verwende ich eine Prüfung in einer while
Schleife, um alte Drehzahlen im Ergebnissatz zu erkennen und zu überschreiben. Aber ist das der einzige Weg, um Ergebnisse zu erzielen? Gibt es keine SQL-Lösung?
我更喜欢尽可能少使用代码...
你可以使用
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、数据库结构、索引等)。因此,在选择一种方法时,要进行基准测试。确保选择对你来说最有意义的方法。