2011-06-07 116 views
0

在Sql Server 2008中,我有一个数据库表,数据中包含一个字段,表示时间段的格式为:2d,1w,4y,其中“d”=日, “w”=周,“y”=年。根据这个字段进行排序的最好方法是什么,以便它们按时间顺序排列(例如“1y”之前的“3w”)?Sql服务器 - 如何排序而不是字母数字

感谢

+0

一位聪明人曾告诉我只按每列存储一条信息。你在这个列中存储多个,这是什么导致你的问题。最好的解决方案是以不同的方式存储数据:可能是3列。 – 2011-06-07 17:48:52

回答

2

我想你是幸运的,d是之前W和W也是前Ÿ所以你可以做

ORDER BY RIGHT(MyField, 1), CONVERT(int, LEFT(Field, LEN(Field) - 1))

但是这不会对8D之前把1瓦特例。

所以替代(更复杂)的解决方案可能是

ORDER BY 
    CASE RIGHT(Field, 1) 
     WHEN 'd' THEN LEFT(Field, LEN(Field) - 1) 
     WHEN 'w' THEN 7*LEFT(Field, LEN(Field) - 1) 
     ELSE 356 * LEFT(Field, LEN(Field) - 1) 
    END 

它使你的数据的假设(例如,仅d,W和Y打算在那里),不采取跨越帐户年(如果有的话)。

+0

2d小于5d - 在你的例子中,这将不会被正确处理。 – CristiC 2011-06-07 14:02:12

+0

@Parkyprg:当然会的。你没有看到第二个排序字段吗? – Ray 2011-06-07 14:04:41

+0

@雷:你不知道可以在那里。例如2d会在10d后出现,因为它是一个字符串。 – CristiC 2011-06-07 14:06:51

2

随着时间的推移,您可能会有不同的时期。所以我会把这段时间放在一个带有ID,时间段和排序顺序(或几天)的新表中。在初始表中,用time_period_id替换该字段,并在您的查询中加入并在SORT BY中使用它。

+0

如果您能够修改架构,这是正确的解决方案。 – Ray 2011-06-07 14:14:29

1

与串数字替换你的角色,并在排序前转换成整数,像:

convert(int, replace(replace(replace(myField,'d',''),'w','0')'y','00')) 

所以你的3D是3,2w为20和4Y是400


思考后有一点,通过案例表达式来计算真实值会更好。例如得到14的2w小于13d。

+0

您可能希望使y 000,否则40w是大于1y = 100的400。 – Ray 2011-06-07 14:08:16

+0

是的,你是对的。所以最好计算真实的时间跨度。 – ibram 2011-06-07 14:11:15

0

我的方法是编写一个函数来解析持续时间字符串,并以尽可能小的单位进行归一化(我假设它是几天,但如果您可以有几个小时或一些较小的单位表达,使用它)。然后,有一个计算列,该列是针对您的列调用的该函数的值。那时,这只是一个比较数字的问题。当然,魔鬼的细节......我不想尝试从T-SQL解析文本。