我对SQL还是很陌生,这让我很困惑。 您可以帮我解决这个查询吗?
我有以下2表:
表1:IssueTable
Id | RunId | VALUE
---
1 | 1 | 10
2 | 1 | 20
3 | 1 | 30
4 | 2 | 40
5 | 2 | 50
6 | 3 | 60
7 | 4 | 70
8 | 5 | 80
9 | 6 | 90
表2:RunTable
RunId | EnvironmentId
---
1 | 1
2 | 3
3 | 1
4 | 2
5 | 4
6 | 2
我需要IssueTable行,这些行代表RunTable中按EnvironmentId分组的Max RunId。 我需要从表中得到的结果是:
预期结果:
Id | RunId | VALUE | EnvironmentId
---
4 | 2 | 40 | 3
5 | 2 | 50 | 3
6 | 3 | 60 | 1
8 | 5 | 80 | 4
9 | 6 | 90 | 2
因此,每个EnvironmentId仅包含RunTable中具有最新/最高RunId的行。 例如,对于EnvironmentId为" 1",我只希望包含RunId为" 3"的行,因为RunTable上EnvironmentId为" 1"的最新RunId为" 3"。 同样,EnvironementId" 2"的最新运行是RunId" 6"
你的rdbms是什么? SQL Server,Postgres,Oracle?
使用子查询从运行表中获取每个环境id的最大runid。 将获得的结果加入发布表,然后选择所需的列。
SELECT i.id, i.runid, i.value, r.environmentid
FROM (SELECT environmentid, MAX(runid) maxrunid
FROM runtable
GROUP BY environmentid) r
JOIN issuetable i ON i.runid = r.maxrunid
ORDER BY i.runid, i.id
如今,您可以使用RANK,DENSE_RANK,ROW_NUMBER等分析功能来对记录进行排名。
窗口函数是ANSI SQL:2003标准的一部分。
而且我至少在TeraData,Oracle和SQL-Server上遇到过它们。
SELECT Id, RunId, VALUE, EnvironmentId
FROM (
SELECT i.*, r.EnvironmentId,
dense_rank() OVER (partition BY r.EnvironmentId ORDER BY r.RunId DESC) AS RN
FROM issuetable i
INNER JOIN runtable r ON (i.RunId = r.RunId)
) Q
WHERE RN = 1
ORDER BY Id;
内部查询将产生以下结果:
Id RunId VALUE EnvironmentId RN
1 1 10 1 2
2 1 20 1 2
3 1 30 1 2
4 2 40 3 1
5 2 50 3 1
6 3 60 1 1
7 4 70 2 2
8 5 80 4 1
9 6 90 2 1
窗口函数是在SQL:2003中引入的,而不是1999年引入的。DB2,Postgres,Firebird和其他几个函数也支持它们
确实,我发现的文章使我错误地假定了这些功能的错误标准。 感谢您指出。 它已在答案中得到纠正。
值得一提的是,ROW_NUMBER()是建议的方法中唯一的一种,即使在多次出现MAX值的情况下,也可以确保每组(分区)恰好有一行记录-并且还易于使用其他字段作为平局 在ORDER BY子句中。