我在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)任何帮助都将不胜感激。
发布于 2015-02-24 16:12:23
要使这类操作正常运行,您基本上没有什么选择:
1)向表中添加一个或多个计算列,可能是每个数字组中的一个列,也可能是一个bigint。有4个单独的列可能是更安全的选择。
2)将4部分字符串拆分添加到select中,它将按句点分隔的每个部分转换为一个数字,并将数据排序为整数。如果您在几个地方有类似的逻辑,那么您最终将复制粘贴相同的代码。
3)创建一个用户定义函数,从版本字符串返回4个数字。易于在多个地方使用,但可能导致性能开销。
4)在创建版本整数的表的顶部创建一个视图。基本上和函数是一样的,如果有很多行(或者经常调用),这并不是最好的方法。
编辑:添加视图的想法。
编辑2:为select添加了示例:
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发布于 2015-02-24 16:19:06
这是一种黑客攻击,可能并不总是起作用,但它适用于您的示例数据,并且应该让您了解您可以做什么:
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,如果第一个数字是0-9,使它00-09,这改变了词法顺序。
发布于 2015-02-24 16:25:13
如果您知道FileVersion表总是像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这将只为表值排序,而不是为每个资源选择一个。
https://stackoverflow.com/questions/28699966
复制相似问题