Bri*_*ian 15 mysql sql greatest-n-per-group
可能重复:
SQL:查找每组的最大记录数
我有一个有四列的表格如下:
name major minor revision
p1 0 4 3
p1 1 0 0
p1 1 1 4
p2 1 1 1
p2 2 5 0
p3 3 4 4
Run Code Online (Sandbox Code Playgroud)
这基本上是包含每个程序版本记录的ca表.我想做一个选择以获取所有程序及其最新版本,因此结果将如下所示:
name major minor revision
p1 1 1 4
p2 2 5 0
p3 3 4 4
Run Code Online (Sandbox Code Playgroud)
我不能只按名称分组并获得每列的最大值,因为那样我最终会得到每列中最高的数字,而不是具有最高版本的特定行.我怎么设置它?
And*_*mar 11
您可以使用not exists子查询过滤掉旧记录:
select *
from YourTable yt
where not exists
(
select *
from YourTable older
where yt.name = older.name and
(
yt.major < older.major or
yt.major = older.major and yt.minor < older.minor or
yt.major = older.major and yt.minor = older.minor and
yt.revision < older.revision
)
)
Run Code Online (Sandbox Code Playgroud)
也可以用MySQL编写:
select *
from YourTable yt
where not exists
(
select *
from YourTable older
where yt.name = older.name and
(yt.major, yt.minor, yt.revision)
< (older.major, older.major, older.revision)
)
Run Code Online (Sandbox Code Playgroud)
我尝试解决SQL问题的方法是一步一步地解决问题.
每种产品的最大主要数量由下式给出:
SELECT Name, MAX(major) AS Major FROM CA GROUP BY Name;
Run Code Online (Sandbox Code Playgroud)
因此,对应于每种产品的最大主要编号的最大次要编号由下式给出:
SELECT CA.Name, CA.Major, MAX(CA.Minor) AS Minor
FROM CA
JOIN (SELECT Name, MAX(Major) AS Major
FROM CA
GROUP BY Name
) AS CB
ON CA.Name = CB.Name AND CA.Major = CB.Major
GROUP BY CA.Name, CA.Major;
Run Code Online (Sandbox Code Playgroud)
因此,最大修订版(对应于每个产品的最大主要编号的最大次要版本号)由下式给出:
SELECT CA.Name, CA.Major, CA.Minor, MAX(CA.Revision) AS Revision
FROM CA
JOIN (SELECT CA.Name, CA.Major, MAX(CA.Minor) AS Minor
FROM CA
JOIN (SELECT Name, MAX(Major) AS Major
FROM CA
GROUP BY Name
) AS CB
ON CA.Name = CB.Name AND CA.Major = CB.Major
GROUP BY CA.Name, CA.Major
) AS CC
ON CA.Name = CC.Name AND CA.Major = CC.Major AND CA.Minor = CC.Minor
GROUP BY CA.Name, CA.Major, CA.Minor;
Run Code Online (Sandbox Code Playgroud)
经过测试 - 它的工作原理与Andomar的查询产生相同的答案.
我创建了更大量的数据(11616行数据),并运行了Andomar对我的查询的基准时间 - 目标DBMS是在MacOS X 10.7.2上运行的IBM Informix Dynamic Server(IDS)版本11.70.FC2.我使用了Andomar的两个查询中的第一个,因为IDS不支持第二个中的比较符号.我加载了数据,更新了统计数据,然后运行查询,然后是Andomar,然后是Andomar,然后是我的.我还记录了IDS优化器报告的基本成本.来自两个查询的结果数据是相同的(因此查询都是准确的 - 或者同样不准确).
表未编入索引:
Andomar's query Jonathan's query
Time: 22.074129 Time: 0.085803
Estimated Cost: 2468070 Estimated Cost: 22673
Estimated # of Rows Returned: 5808 Estimated # of Rows Returned: 132
Temporary Files Required For: Order By Temporary Files Required For: Group By
Run Code Online (Sandbox Code Playgroud)
具有唯一索引的表(名称,主要,次要,修订):
Andomar's query Jonathan's query
Time: 0.768309 Time: 0.060380
Estimated Cost: 31754 Estimated Cost: 2329
Estimated # of Rows Returned: 5808 Estimated # of Rows Returned: 139
Temporary Files Required For: Group By
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,该索引显着提高了Andomar查询的性能,但在此系统上它仍然比我的查询更昂贵.该索引为我的查询节省了25%的时间.我很想看到两个版本的Andomar对可比数据量的查询的可比数据,无论是否有索引.(如果您需要,我可以提供我的测试数据;有132种产品 - 问题中列出的3种产品和129种新产品;每种新产品都有(相同的)90种版本条目.)
出现差异的原因是Andomar查询中的子查询是一个相关的子查询,这是一个相对昂贵的过程(当索引丢失时非常显着).