我有一个这样的数据库表:
id version_id field1 field2
1 1 texta text1
1 2 textb text2
2 1 textc text3
2 2 textd text4
2 3 texte text5
如果你没有解决它,它包含一行的多个版本,然后是一些文本数据。
我想查询它并返回每个id的编号最大的版本。 (所以只有上面的第二行和最后一行)。
我尝试使用group by by version_id DESC进行排序 - 但它似乎在分组后进行排序,所以这不起作用。
有人有任何想法吗?我无法相信它无法完成!
更新:
想出这个,它有效,但使用子查询:
SELECT *
FROM (SELECT * FROM table ORDER BY version_id DESC) t1
GROUP BY t1.id
答案 0 :(得分:49)
它被称为选择列的组最大值。 Here are several different approaches for mysql.
我将如何做到这一点:
SELECT *
FROM (SELECT id, max(version_id) as version_id FROM table GROUP BY id) t1
INNER JOIN table t2 on t2.id=t1.id and t1.version_id=t2.version_id
这将是相对有效的,尽管mysql将在内存中为子查询创建一个临时表。我假设你已经有了这个表的(id,version_id)索引。
在SQL中,您或多或少必须使用子查询来解决此类问题(semi-joins是另一个示例)。
子查询在mysql中没有得到很好的优化,但是不相关的子查询并不是那么糟糕,只要它们不是那么庞大以至于它们将被写入磁盘而不是内存。鉴于在此查询中只有两个整数,子查询在发生之前可能长达数百万行,但第一个查询中的select *子查询可能会更快地遇到此问题。
答案 1 :(得分:3)
我认为这会做到这一点,不确定它是否是最好或最快的。
SELECT * FROM table
WHERE (id, version_id) IN
(SELECT id, MAX(version_id) FROM table GROUP BY id)
答案 2 :(得分:2)
SELECT id, version_id, field1, field2
FROM (
SELECT @prev = id AS st, (@prev := id), m.*
FROM (
(SELECT @prev := NULL) p,
(
SELECT *
FROM mytable
ORDER BY
id DESC, version_id DESC
) m
) m2
WHERE NOT IFNULL(st, FALSE);
没有子查询,UNIQUE INDEX ON MYTABLE (id, version_id)
如果你有一个(我认为你应该这样做),可以传递一个
答案 3 :(得分:0)
这是伪代码,但像这样的东西应该可以正常工作
select *
from table
inner join
(
select id , max(version_id) maxVersion
from table
) dvtbl ON id = dvtbl.id && versionid = dvtbl.maxVersion
答案 4 :(得分:0)
我通常使用子查询执行此操作:
从datatable中选择id,version_id,field1,field2作为dt,其中id =(从datatable中选择id,其中id = dt.id按version_id desc limit 1顺序)
答案 5 :(得分:0)
此查询将在没有组的情况下执行以下任务:
SELECT * FROM table AS t
LEFT JOIN table AS t2
ON t.id=t2.id
AND t.version_id < t2.version_id
WHERE t2.id IS NULL
它不需要任何临时表。
答案 6 :(得分:0)
一个人总是可以使用分析功能,这将给您更多的控制权
select tmp.* from ( select id,version_id,field1,field2, rank() over(partition by id order by version_id desc ) as rnk from table) tmp where tmp.rnk=1
如果根据数据类型遇到rank()函数的问题,那么也可以从row_number()或density_rank()中进行选择。
答案 7 :(得分:-1)
我认为这就是你想要的。
select id, max(v_id), field1, field2 from table group by id
我得到的结果是
1,2,textb,text2
2,3,texte,text5
修改强> 我重新创建了表并插入了与id相同的数据,而version_id是复合主键。这给出了我之前提供的答案。它也在MySQL中。
答案 8 :(得分:-2)
没有测试过,但这样的事情可能有用:
SELECT * FROM table GROUP BY id ORDER BY MAX(version_id)DESC