我在SQL Server 2008中有一个表,其中包含资源ID和某个文件的相应版本:
ResourceID FileVersion
1 8.00.7601.17514 (win7sp1_rtm.101119-1850)
1 11.00.9600.16428 (winblue_gdr.131013-1700)
1 11.00.9600.17041 (winblue_gdr.140305-1710)
1 11.00.9600.17126 (winblue_gdr_escrow.140529-2055)
2 8.00.7601.18472 (win7SP1_GDR_escrow.140527-0630)
2 8.00.7601.22686 (win7SP1_LDR_escrow.140527-0630)
2 11.00.9600.17239 (winblue_gdr.140724-2228)
2 11.00.9600.17420 (winblue_r4.141105-1535)
2 11.00.9600.17496 (winblue_r5.141121-1500)
我想找到每个资源ID的最大版本。在这种情况下,所需的输出是
ResourceID FileVersion
1 11.00.9600.17126 (winblue_gdr_escrow.140529-2055)
2 11.00.9600.17496 (winblue_r5.141121-1500)
我尝试过以下代码:
Select ResourceID, MAX(SUBSTRING(FileVersion,1,CHARINDEX(' ',FileVersion + ' ')-1))
From VersionTable
Group By ResourceID
但是得到以下输出:
ResourceID FileVersion
1 8.00.7601.17514 (win7sp1_rtm.101119-1850)
2 8.00.7601.22686 (win7SP1_LDR_escrow.140527-0630)
任何帮助都将不胜感激。
答案 0 :(得分:1)
要使排序正常工作,您基本上没有多少选择:
1)向表中添加一个或多个计算列,可能每个数组或一个bigint一个。有4个单独的列可能是更安全的选择。
2)将4部分字符串拆分为select,将每个由句点分隔的部分转换为数字,并将数据排序为整数。如果你在几个地方有类似的逻辑,那么你最终会在整个地方复制粘贴相同的代码。
3)创建一个用户定义的函数,从版本字符串返回4个数字。易于在多个地方使用,但可能会导致性能开销。
4)在表的顶部创建一个创建版本整数的视图。基本上和功能一样,如果有很多行(或经常被称为),那就不是最好的了。
编辑:为视图添加了想法。
编辑2:添加了选择的示例:
select
ResourceID,
ver
from (
select
ResourceID,
v.ver,
row_number() over (partition by ResourceID
order by n.v1 desc, n.v2 desc, n.v3 desc, n.v4 desc) as rn
from VersionTable
cross apply (
select left(FileVersion, charindex(' ', FileVersion)-1) as ver
) as v
cross apply (
select charindex('.', v.ver) as p
) as p1
cross apply (
select charindex('.', v.ver, p1.p+1) as p
) as p2
cross apply (
select charindex('.', v.ver, p2.p+1) as p
) as p3
cross apply (
select
convert(int, left(v.ver, p1.p - 1)) as v1,
convert(int, substring(v.ver, p1.p+1, p2.p-p1.p-1)) as v2,
convert(int, substring(v.ver, p2.p+1, p3.p-p2.p-1)) as v3,
convert(int, substring(v.ver, p3.p+1, 999)) as v4
) as n
) tmp
where rn = 1
答案 1 :(得分:1)
这是一个黑客,可能不会一直有效,但它确实对您的示例数据有所帮助,应该让您知道您可以做什么:
Select
ResourceID,
max(
case
when charindex('.', fileversion, 0) = 2
then STUFF(LEFT(FileVersion, CHARINDEX(' ', FileVersion,0)-1), 1, 1, '0'+left(fileversion, 1))
else LEFT(FileVersion, CHARINDEX(' ', FileVersion,0)-1)
end
)
From VersionTable
group by ResourceID
如果第一个数字为0-9,则输入0,使其变为00-09,从而改变词汇顺序。
答案 2 :(得分:0)
如果你知道你将永远拥有像number.number.number.number
此代码可以使用。基本上它为版本的每个部分创建4个整数,并从左侧开始按顺序排序(重要性更高的数字)
SELECT * FROM VersionTable
ORDER BY substring([FileVersion],0,charindex('.',[FileVersion])) DESC,
substring(substring([FileVersion],charindex('.',[FileVersion])+1,LEN([FileVersion])),0,charindex('.',substring([FileVersion],charindex('.',[FileVersion])+1,LEN([FileVersion])))) DESC,
substring(substring(substring([FileVersion],charindex('.',[FileVersion])+1,LEN([FileVersion])),charindex('.',substring([FileVersion],charindex('.',[FileVersion])+1,LEN([FileVersion])))+1,LEN(substring([FileVersion],charindex('.',[FileVersion])+1,LEN([FileVersion]))))
,0,charindex('.',substring(substring([FileVersion],charindex('.',[FileVersion])+1,LEN([FileVersion])),charindex('.',substring([FileVersion],charindex('.',[FileVersion])+1,LEN([FileVersion])))+1,LEN(substring([FileVersion],charindex('.',[FileVersion])+1,LEN([FileVersion])))))),
reverse(substring(reverse([FileVersion]), 0 , charindex('.',reverse([FileVersion])))) DESC
这将为您的表值排序,而不是为每个资源选择一个。