SQL 服务器 Select 最大版本值
SQL Server Select MAX Version Value
我在 table 中有两列名为 id 和 version,如下所示:
ID | Version |
1 | A.15 |
1 | Z.6 |
1 | C.5 |
1 | BD.3 |
1 | BD.2 |
1 | AB.13 |
2 | C.45 |
2 | Z.56 |
2 | Z.8 |
我的要求是 table 中的每个 ID 必须 select max(Version)。在这种情况下,我应该得到以下结果:
|ID | MAX(Version)|
| 1 | BD.3 |
| 2 | Z.56 |
但我得到以下结果:
|ID | MAX(Version)|
| 1 | Z.6 |
| 2 | Z.8 |
当我使用这个查询时:
SELECT ID,MAX(Version)
FROM table
GROUP BY ID
请给我建议好的解决方案以获得我想要的结果。
谢谢。
我想你想要以下内容:
SELECT ID,MAX(SUBSTRING(Version,charindex('.',Version),Len(Version)-charindex('.',Version)))
FROM table
GROUP BY ID
基本上上面的代码获取'.'之后的子字符串,因此 Version 的数字部分并找到该部分的最大值
您可以通过查找 .
之后的值来去除字符串的数字部分,如下所示:
DECLARE @val VARCHAR(5) = 'BD.34'
SELECT CONVERT(INT, RIGHT(@val, LEN(@val) - CHARINDEX('.', @val))) AS Result
Result
======
34
然后,您可以将其纳入子查询,以使用 GROUP BY
和 MAX
重新连接到主 table,如下所示:
可运行代码:
CREATE TABLE #Versions
(
[ID] INT ,
[Version] VARCHAR(5)
);
INSERT INTO #Versions
( [ID], [Version] )
VALUES ( 1, 'A.15' ),
( 1, 'Z.6' ),
( 1, 'C.5' ),
( 1, 'BD.34' ),
( 1, 'BD.25' ),
( 1, 'AB.13' ),
( 2, 'C.45' ),
( 2, 'Z.56' ),
( 2, 'Z.8' );
SELECT v.ID ,
v.Version
FROM #Versions v
INNER JOIN (
SELECT ID ,
MAX(CONVERT(INT,
RIGHT(Version,
LEN(Version) - CHARINDEX('.', Version)))) AS VersionNo
FROM #Versions
GROUP BY ID
) t ON t.ID = v.ID
AND '.' + CONVERT(VARCHAR(5), t.VersionNo) = '.'
+ RIGHT(v.Version,
LEN(v.Version) - CHARINDEX('.', v.Version))
DROP TABLE #Versions
产生:
ID Version
1 BD.34
2 Z.56
使用的连接将连接 MAX
版本号,保存在 VersionNo
回到主 table,我已经在连接上添加了 '.'
和假设您的版本将始终采用以下格式:字符后跟 period/full 停止符和数字部分。
我们这里不需要小组。它可以通过一个相对简单的查询来完成。查询中使用的逻辑与其他答案中使用的逻辑类似。
SELECT ID,version
FROM tmp a
where CAST(SUBSTRING(version,charindex('.',version)+1,Len(version)-charindex('.',version)) as integer)=
(select MAX(CAST(SUBSTRING(version,charindex('.',version)+1,Len(version)-charindex('.',version)) as integer)) from tmp b where a.id=b.id)
这是我的方式(我们不关心字母,只关注数字)
DECLARE @MyTable TABLE(ID INT, Version VARCHAR(10))
INSERT INTO @MyTable VALUES(1,'A.15')
,(1,'Z.6')
,(1,'C.5')
,(1,'BD.34')
,(1,'BD.25')
,(1,'AB.13')
,(2,'C.45')
,(2,'Z.56')
,(2,'Z.8')
SELECT t1.ID, t1.Version
FROM @MyTable AS t1
INNER JOIN (
SELECT Id, MAX(CONVERT(INT,SUBSTRING(Version,CHARINDEX('.',Version)+1,LEN(Version)))) AS Number
FROM @MyTable
GROUP By ID ) AS t2
ON t1.ID = t2.ID AND CONVERT(INT,SUBSTRING(t1.Version,CHARINDEX('.',t1.Version)+1,LEN(t1.Version))) = t2.Number
试试这个:
DECLARE @MyTable TABLE(ID INT, Version VARCHAR(10))
INSERT INTO @MyTable
VALUES (1,'A.15'), (1,'Z.6'), (1,'C.5'), (1,'BD.3'), (1,'BD.2'),
(1,'AB.13'), (2,'C.45'), (2,'Z.56'), (2,'Z.8')
--
SELECT
ID,
Version
FROM
(
SELECT
ID,
Version,
ROW_NUMBER() OVER
(
PARTITION BY ID
ORDER BY LEN(LEFT(Version, CHARINDEX('.',Version)-1)) DESC,
LEFT(Version, CHARINDEX('.',Version)-1) DESC,
CAST(STUFF(Version, 1, CHARINDEX('.',Version),'') AS INT) DESC
) AS Pos
FROM
@MyTable
) T
WHERE Pos = 1
我在 table 中有两列名为 id 和 version,如下所示:
ID | Version |
1 | A.15 |
1 | Z.6 |
1 | C.5 |
1 | BD.3 |
1 | BD.2 |
1 | AB.13 |
2 | C.45 |
2 | Z.56 |
2 | Z.8 |
我的要求是 table 中的每个 ID 必须 select max(Version)。在这种情况下,我应该得到以下结果:
|ID | MAX(Version)|
| 1 | BD.3 |
| 2 | Z.56 |
但我得到以下结果:
|ID | MAX(Version)|
| 1 | Z.6 |
| 2 | Z.8 |
当我使用这个查询时:
SELECT ID,MAX(Version)
FROM table
GROUP BY ID
请给我建议好的解决方案以获得我想要的结果。 谢谢。
我想你想要以下内容:
SELECT ID,MAX(SUBSTRING(Version,charindex('.',Version),Len(Version)-charindex('.',Version)))
FROM table
GROUP BY ID
基本上上面的代码获取'.'之后的子字符串,因此 Version 的数字部分并找到该部分的最大值
您可以通过查找 .
之后的值来去除字符串的数字部分,如下所示:
DECLARE @val VARCHAR(5) = 'BD.34'
SELECT CONVERT(INT, RIGHT(@val, LEN(@val) - CHARINDEX('.', @val))) AS Result
Result
======
34
然后,您可以将其纳入子查询,以使用 GROUP BY
和 MAX
重新连接到主 table,如下所示:
可运行代码:
CREATE TABLE #Versions
(
[ID] INT ,
[Version] VARCHAR(5)
);
INSERT INTO #Versions
( [ID], [Version] )
VALUES ( 1, 'A.15' ),
( 1, 'Z.6' ),
( 1, 'C.5' ),
( 1, 'BD.34' ),
( 1, 'BD.25' ),
( 1, 'AB.13' ),
( 2, 'C.45' ),
( 2, 'Z.56' ),
( 2, 'Z.8' );
SELECT v.ID ,
v.Version
FROM #Versions v
INNER JOIN (
SELECT ID ,
MAX(CONVERT(INT,
RIGHT(Version,
LEN(Version) - CHARINDEX('.', Version)))) AS VersionNo
FROM #Versions
GROUP BY ID
) t ON t.ID = v.ID
AND '.' + CONVERT(VARCHAR(5), t.VersionNo) = '.'
+ RIGHT(v.Version,
LEN(v.Version) - CHARINDEX('.', v.Version))
DROP TABLE #Versions
产生:
ID Version
1 BD.34
2 Z.56
使用的连接将连接 MAX
版本号,保存在 VersionNo
回到主 table,我已经在连接上添加了 '.'
和假设您的版本将始终采用以下格式:字符后跟 period/full 停止符和数字部分。
我们这里不需要小组。它可以通过一个相对简单的查询来完成。查询中使用的逻辑与其他答案中使用的逻辑类似。
SELECT ID,version
FROM tmp a
where CAST(SUBSTRING(version,charindex('.',version)+1,Len(version)-charindex('.',version)) as integer)=
(select MAX(CAST(SUBSTRING(version,charindex('.',version)+1,Len(version)-charindex('.',version)) as integer)) from tmp b where a.id=b.id)
这是我的方式(我们不关心字母,只关注数字)
DECLARE @MyTable TABLE(ID INT, Version VARCHAR(10))
INSERT INTO @MyTable VALUES(1,'A.15')
,(1,'Z.6')
,(1,'C.5')
,(1,'BD.34')
,(1,'BD.25')
,(1,'AB.13')
,(2,'C.45')
,(2,'Z.56')
,(2,'Z.8')
SELECT t1.ID, t1.Version
FROM @MyTable AS t1
INNER JOIN (
SELECT Id, MAX(CONVERT(INT,SUBSTRING(Version,CHARINDEX('.',Version)+1,LEN(Version)))) AS Number
FROM @MyTable
GROUP By ID ) AS t2
ON t1.ID = t2.ID AND CONVERT(INT,SUBSTRING(t1.Version,CHARINDEX('.',t1.Version)+1,LEN(t1.Version))) = t2.Number
试试这个:
DECLARE @MyTable TABLE(ID INT, Version VARCHAR(10))
INSERT INTO @MyTable
VALUES (1,'A.15'), (1,'Z.6'), (1,'C.5'), (1,'BD.3'), (1,'BD.2'),
(1,'AB.13'), (2,'C.45'), (2,'Z.56'), (2,'Z.8')
--
SELECT
ID,
Version
FROM
(
SELECT
ID,
Version,
ROW_NUMBER() OVER
(
PARTITION BY ID
ORDER BY LEN(LEFT(Version, CHARINDEX('.',Version)-1)) DESC,
LEFT(Version, CHARINDEX('.',Version)-1) DESC,
CAST(STUFF(Version, 1, CHARINDEX('.',Version),'') AS INT) DESC
) AS Pos
FROM
@MyTable
) T
WHERE Pos = 1