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

参见:http://sqlfiddle.com/#!18/93a572/15/0

从子查询开始,为每个用户查找“最新”版本。在这种情况下,“最新”被定义为每个用户具有最大 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'

Fiddle here.