题
我在 nvarchar 列(单词和数字)中有混合数据。这是按数字顺序对该列中的数据进行排序的最快方法。
结果示例:
- 1
- 2
- 3
- ...
- 10
- 11
- ...
- 啊啊啊
- 啊阿布
- 乙
- 巴
- 巴
- ...
解决方案
用这个:
ORDER BY
CASE WHEN ISNUMERIC(column) = 1 THEN 0 ELSE 1 END,
CASE WHEN ISNUMERIC(column) = 1 THEN CAST(column AS INT) ELSE 0 END,
column
这按预期工作。
笔记: :你说 最快的方式. 。这个 SQL 对我来说生成速度很快,但执行计划显示了表扫描,然后是标量计算。这可能会产生一个临时结果,其中包含该列的所有值以及一些用于 ISNUMERIC 结果的额外临时列。执行起来可能不快。
其他提示
如果你用 0 填充你的数字并对其进行排序,你将得到你想要的结果。您需要确保填充的 0 数量与 varchar 列的大小匹配。
看看这个例子......
Declare @Temp Table(Data VarChar(20))
Insert Into @Temp Values('1')
Insert Into @Temp Values('2')
Insert Into @Temp Values('3')
Insert Into @Temp Values('10')
Insert Into @Temp Values('11')
Insert Into @Temp Values('aaaa')
Insert Into @Temp Values('aaab')
Insert Into @Temp Values('b')
Insert Into @Temp Values('ba')
Insert Into @Temp Values('ba')
Select * From @Temp
Order By Case When IsNumeric(Data) = 1
Then Right('0000000000000000000' + Data, 20)
Else Data End
另请注意,使用 case 语句时,case 语句的每个分支返回相同的数据类型,这一点很重要,否则您将得到不正确的结果或错误。
--检查是否存在
如果存在(从 dbo.sysobjects 选择 *,其中 [id] = object_id(N'dbo.t') AND objectproperty(id, N'IsUserTable') = 1)
删除表 dbo.t
去
--创建示例表
创建表 dbo.t (c varchar(10) 不为空)
设置不计数
--填充示例表
插入 dbo.t (c) 值 ('1')
插入 dbo.t (c) 值 ('2')
插入 dbo.t (c) 值 ('3')
插入 dbo.t (c) 值 ('10')
插入 dbo.t (c) 值 ('11')
插入 dbo.t (c) 值 ('aaaa')
插入 dbo.t (c) 值 ('aaab')
插入 dbo.t (c) 值 ('b')
插入 dbo.t (c) 值 ('ba')
插入 dbo.t (c) 值 ('ba')
--返回数据
从 dbo.t 选择 c
按情况排序,当 isnumeric(c) = 1 时为 0,否则为 1 结束,
当 isnumeric(c) = 1 时则强制转换(c as int) else 0 结束,
C
您可以将数据视为字母数字或数字,但不能同时将两者视为两者。我认为您尝试做的事情是不可能的,数据模型没有正确设置。
我不认为你想做的是可能的
这个例子效果很好
SELECT * FROM TableName
ORDER BY CASE WHEN 1 = IsNumeric(ColumnName) THEN Cast(ColumnName AS INT) END
结果是:
- A
- 乙
- C
- ...
- 1
- 2
- 3
但我首先需要数字。
这应该有效:
select * from Table order by ascii(Column)
投射它。
SELECT * FROM foo ORDER BY CAST(somecolumn AS int);
自从我接触 SQL Server 以来已经有一段时间了,所以我的语法可能完全不正确:)