我需要一些有关 MySQL 请求的帮助,以仅选择列上具有最大值的行。
我已经阅读并实现了那里给出的解决方案: SQL Select only rows with Max Value on a Column
SELECT * FROM yourtable AS yt1
LEFT OUTER JOIN yourtable yt2 ON (yt1.id = yt2.id AND yt1.rev < yt2.rev)
WHERE yt2.id IS NULL;
它工作正常,但前提是您要过滤的字段实际上是最大值或最小值。
如果您想过滤自定义订单怎么办?
id rev content..
.1. 1
.2 1......---...
.1 2......---...
.1 3......---...
也就是说,不是选择上表中的两行:[1, 3, ...]
和 [2, 1, ..]
,您希望你的结果集是 [1, 2, ...]
和 [2, 1, ..]
因为已经确定 rev=2 有更高的优先于 rev=3
和 rev=1
。
是否需要重新定义“<”或其他内容的顺序关系?
我宁愿避免使用子选择。
谢谢。
最佳答案
示例数据:
CREATE TABLE yourtable
(`id` int, `rev` int, content varchar(20))
;
INSERT INTO yourtable
(`id`, `rev`, content)
VALUES
(1, 1, 'a'),
(2, 1, 'b'),
(1, 2, 'c'),
(1, 3, 'd')
;
解决方案一:
SELECT * FROM yourtable AS yt1
LEFT OUTER JOIN yourtable yt2 ON (yt1.id = yt2.id AND FIELD(yt1.rev, 1,3,2) < FIELD(yt2.rev, 1,3,2))
WHERE yt2.id IS NULL;
但我不喜欢在联接的列上使用函数,尤其是在进行范围比较而不是相等比较时。
解决方案 2:
SELECT id, rev, content FROM (
SELECT yt.*, @grpnum := IF(id != @prevgrp, 1, @grpnum + 1) as my_filter, @prevgrp := id
FROM yourtable yt,
(SELECT @grpnum:=0, @prevgrp := 0) v
ORDER BY id, FIELD(rev, 1, 3, 2) DESC
) sq
WHERE my_filter = 1;
结果:
| ID | REV | CONTENT |
|----|-----|---------|
| 1 | 2 | c |
| 2 | 1 | b |
- 看到它在 sqlfiddle 中实时运行
解释方案二:
首先,我从 yourtable
中选择所有内容,然后按 id
排序,然后按 FIELD(rev, 1, 3, 2)
排序。这个 FIELD()
函数有什么作用?
考虑这个数据:
mysql> select id from value order by id;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+----+
现在,当你这样做的时候
mysql> select id, field(id, 3,2,5) from value order by id;
+----+------------------+
| id | field(id, 3,2,5) |
+----+------------------+
| 1 | 0 |
| 2 | 2 |
| 3 | 1 |
| 4 | 0 |
| 5 | 3 |
| 6 | 0 |
+----+------------------+
你看,该函数返回函数参数列表中 id
列的索引。未找到的所有内容都返回为 0
。
阅读更多相关信息 here in the manual .
因为我们想要最大值,所以我们翻转了 FIELD()
参数列表中的顺序。 FIELD(rev, 2, 3, 1)
我们有 FIELD(rev, 1, 3, 2)
假设优先顺序为 2最高,然后是 3,然后是 1。 (编辑:我现在刚刚看到,您有另一个订单,您当然也可以使用您的 CASE WHEN
构造,它的作用相同,FIELD()
功能就是少写)
下一步是在别名为 v
的子查询中动态初始化一些变量。这与在查询之前写 SET @grpnum = 0;
是一样的。
当 id 改变时(请注意,我们按 id
排序很重要,然后按 field()
),我们增加另一个变量。这在外部查询中用作过滤器。
这样我们就可以返回与您在 FIELD()
函数中定义的最大值对应的所有行。
关于mysql - SQL 仅选择列上具有自定义最大值的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20491912/