sql - 对包含整数、小数和字符串的字符串字段进行排序 SQL
问题描述
我继承了一个项目,该项目有一个可以包含字符串、小数或整数的表。
我需要对这个字段进行排序。
假设我一次只能(基于 id)抓取一种类型,但可以肯定的是,我仍想在排序之前确认类型,如果不是完全相同的类型,只需按字符串排序。
所以桌子可能看起来像这样。
select id, fkID, myValue from myTable
id |fkID|myValue
____|____|_______
1 |14 |abc
2 |14 |ghi
3 |14 |def
4 |11 |2000
5 |11 |1500
6 |11 |10000
7 |17 |110.04
8 |17 |500.22
9 |17 |100.99
然后说我可以抓住所有fkID
11 个。我希望它排序
5 |11 |1500
4 |11 |2000
6 |11 |10000
或者fkID
14 将是
1 |14 |abc
3 |14 |def
2 |14 |ghi
我不知道如何解决这个问题,但尝试使用 Try_Parse 来确定列的值。
如果那行得通,动态sql就可以了。
解决方案
看起来您继承的结构在 sql-server 或任何主要数据库中都没有得到很好的处理(让我想起了过度规范化的 EAV 和 OTLT 模式)。
你可以:
- 如果可用,请使用 try_convert 捕获十进制表示。
- 使用窗口最大值来识别是否有任何非小数。
- 使用使用不同版本的 row_number 的条件语句来获取您的排序。
这是在行动:
declare @fkId int = 11;
select t.*,
ord = iif(
max(iif(decVal is null, 1, 0)) over() = 1, -- has any non decimals?
row_number() over(order by myValue), -- string ordering
row_number() over(order by decVal) -- decimal ordering
)
from @myTable t
cross apply (select decVal = try_convert(decimal(10,2), myValue)) ap
where fkId = @fkId -- replace this with whatever.
order by ord;