Select 预定义的最大值
Select a predefined maximum value
我有一个 table 我的用户数据。
Id
Name
VersionId
1
Name A
1
2
Name B
2
3
Name C
1
4
Name A
2
5
Name E
1
6
Name F
3
7
Name G
2
8
Name C
4
9
Name A
5
还有第二个 table,我代表每个用户所在的版本:
Id
Version
1
1.2
2
1.3
3
1.4
4
1.5
5
1.6
我在向当前版本为 1.3 的 return 用户编写查询时遇到问题。如果用户在某个时候已经拥有 1.3 版本,但目前已不在其中,则不应选择此值。
随着时间的推移,用户可以过渡到多个版本。在查询中,我只想要当前使用 1.3 版的用户。也就是说,只有 Id 为:2 和 7 的用户。
您可以将 MAX 与分区一起使用。在这里,我假设如果用户的版本高于 1.3,那么该用户已经是 1.3,因此 WHERE 子句可以 return 只有 1.3 的那些用户。
DROP TABLE IF EXISTS #userdata;
CREATE TABLE dbo.#userdata(
[Id] INT,
[Name] VARCHAR(100),
[VersionId] INT
);
GO
INSERT INTO dbo.#userdata ([Id],[Name],[VersionId])
SELECT 1, 'Name A', 1 UNION ALL
SELECT 2, 'Name B', 2 UNION ALL
SELECT 3, 'Name C', 1 UNION ALL
SELECT 4, 'Name A', 2 UNION ALL
SELECT 5, 'Name E', 1 UNION ALL
SELECT 6, 'Name F', 3 UNION ALL
SELECT 7, 'Name G', 2 UNION ALL
SELECT 8, 'Name C', 4 UNION ALL
SELECT 9, 'Name A', 5;
DROP TABLE IF EXISTS #versiondata;
CREATE TABLE dbo.#versiondata(
[Id] INT,
[Version] DECIMAL(18, 6)
);
GO
INSERT INTO dbo.#versiondata ([Id],[Version])
SELECT 1, 1.2 UNION ALL
SELECT 2, 1.3 UNION ALL
SELECT 3, 1.4 UNION ALL
SELECT 4, 1.5 UNION ALL
SELECT 5, 1.6;
WITH mx AS (
SELECT DISTINCT
u.Name,
MAX(v.Version) OVER (PARTITION BY u.Name) Version
FROM #userdata u
INNER JOIN #versiondata v ON v.id = u.VersionId
)
SELECT mx.Name, mx.Version
FROM mx
WHERE mx.Version = 1.3;
您可以像这样使用窗口函数返回每个用户的最后一个条目
SELECT
x.Id, x.Name
FROM (SELECT
Id,
Name,
VersionId,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Id DESC) AS rowNum
FROM UserData) x
INNER JOIN VersionData v
ON x.VersionId = v.Id
WHERE
x.rowNum = 1 AND
v.Version = '1.3'
即使用户降级到以前的版本,这仍然有效。
Returns
Id
Name
2
Name B
7
Name G
从子查询开始,为每个用户查找“最新”版本。在这种情况下,“最新”被定义为每个用户具有最大 id
值的行。
SELECT MAX(Id) Id
FROM usertable
GROUP BY Name
然后使用子查询从您的用户表中获取您需要的行,连接到您的版本表,并使用适当的 WHERE 子句。
SELECT versiontable.Version, usertable.Name
FROM versiontable
JOIN usertable on versiontable.Id = usertable.VersionId
JOIN (
SELECT MAX(Id) Id
FROM usertable
GROUP BY Name
) m ON usertable.Id = m.Id
WHERE Version = '1.3'
我有一个 table 我的用户数据。
Id | Name | VersionId |
---|---|---|
1 | Name A | 1 |
2 | Name B | 2 |
3 | Name C | 1 |
4 | Name A | 2 |
5 | Name E | 1 |
6 | Name F | 3 |
7 | Name G | 2 |
8 | Name C | 4 |
9 | Name A | 5 |
还有第二个 table,我代表每个用户所在的版本:
Id | Version |
---|---|
1 | 1.2 |
2 | 1.3 |
3 | 1.4 |
4 | 1.5 |
5 | 1.6 |
我在向当前版本为 1.3 的 return 用户编写查询时遇到问题。如果用户在某个时候已经拥有 1.3 版本,但目前已不在其中,则不应选择此值。 随着时间的推移,用户可以过渡到多个版本。在查询中,我只想要当前使用 1.3 版的用户。也就是说,只有 Id 为:2 和 7 的用户。
您可以将 MAX 与分区一起使用。在这里,我假设如果用户的版本高于 1.3,那么该用户已经是 1.3,因此 WHERE 子句可以 return 只有 1.3 的那些用户。
DROP TABLE IF EXISTS #userdata;
CREATE TABLE dbo.#userdata(
[Id] INT,
[Name] VARCHAR(100),
[VersionId] INT
);
GO
INSERT INTO dbo.#userdata ([Id],[Name],[VersionId])
SELECT 1, 'Name A', 1 UNION ALL
SELECT 2, 'Name B', 2 UNION ALL
SELECT 3, 'Name C', 1 UNION ALL
SELECT 4, 'Name A', 2 UNION ALL
SELECT 5, 'Name E', 1 UNION ALL
SELECT 6, 'Name F', 3 UNION ALL
SELECT 7, 'Name G', 2 UNION ALL
SELECT 8, 'Name C', 4 UNION ALL
SELECT 9, 'Name A', 5;
DROP TABLE IF EXISTS #versiondata;
CREATE TABLE dbo.#versiondata(
[Id] INT,
[Version] DECIMAL(18, 6)
);
GO
INSERT INTO dbo.#versiondata ([Id],[Version])
SELECT 1, 1.2 UNION ALL
SELECT 2, 1.3 UNION ALL
SELECT 3, 1.4 UNION ALL
SELECT 4, 1.5 UNION ALL
SELECT 5, 1.6;
WITH mx AS (
SELECT DISTINCT
u.Name,
MAX(v.Version) OVER (PARTITION BY u.Name) Version
FROM #userdata u
INNER JOIN #versiondata v ON v.id = u.VersionId
)
SELECT mx.Name, mx.Version
FROM mx
WHERE mx.Version = 1.3;
您可以像这样使用窗口函数返回每个用户的最后一个条目
SELECT
x.Id, x.Name
FROM (SELECT
Id,
Name,
VersionId,
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Id DESC) AS rowNum
FROM UserData) x
INNER JOIN VersionData v
ON x.VersionId = v.Id
WHERE
x.rowNum = 1 AND
v.Version = '1.3'
即使用户降级到以前的版本,这仍然有效。
Returns
Id | Name |
---|---|
2 | Name B |
7 | Name G |
从子查询开始,为每个用户查找“最新”版本。在这种情况下,“最新”被定义为每个用户具有最大 id
值的行。
SELECT MAX(Id) Id
FROM usertable
GROUP BY Name
然后使用子查询从您的用户表中获取您需要的行,连接到您的版本表,并使用适当的 WHERE 子句。
SELECT versiontable.Version, usertable.Name
FROM versiontable
JOIN usertable on versiontable.Id = usertable.VersionId
JOIN (
SELECT MAX(Id) Id
FROM usertable
GROUP BY Name
) m ON usertable.Id = m.Id
WHERE Version = '1.3'