我在 SQL Server 中有一个包含此数据的表:
Id
=====
1
12e
5
我想像这样订购这些数据:
id
====
1
5
12e
我的id
列是类型nvarchar(50)
,我无法将其转换为int
.
我可以以这种方式对数据进行排序吗?
我在 SQL Server 中有一个包含此数据的表:
Id
=====
1
12e
5
我想像这样订购这些数据:
id
====
1
5
12e
我的id
列是类型nvarchar(50)
,我无法将其转换为int
.
我可以以这种方式对数据进行排序吗?
作为一般规则,如果您发现自己操作了部分列,那么您几乎肯定做错了。
如果您的 ID 由数字和字母组成,并且您只需要摆弄数字位,请将其设置为两列并省去一些焦虑。在这种情况下,您有一个积分id_numeric
和一个 varchar id_alpha
,您的查询很简单:
select char(id_numeric) | id_alpha as id
from mytable
order by id_numeric asc
或者,如果您确实必须将其存储为单个列,请创建额外的列来保存各个部分并将其用于排序和选择。但是,为了缓解连续重复数据的问题,请使用触发器来确保数据保持一致:
select id
from mytable
order by id_numeric asc
您通常不希望对每个选择都进行这种拆分,因为这永远不会很好地扩展。通过将其作为更新/插入触发器进行,您仅在需要时(即,当数据更改时)进行拆分,并且此成本在所有选择中分摊。这是一个好主意,因为在绝大多数情况下,数据库的读取频率远高于写入频率。
如果您了解并减轻后果,出于性能原因恢复到较低级别的规范化是完全正常的做法。
我实际上会使用与此功能类似的东西,但要注意它不会超快。我已修改该函数以仅返回数字:
CREATE FUNCTION dbo.UDF_ParseNumericChars
(
@string VARCHAR(8000)
)
RETURNS VARCHAR(8000)
WITH SCHEMABINDING
AS
BEGIN
DECLARE @IncorrectCharLoc SMALLINT
SET @IncorrectCharLoc = PATINDEX('%[^0-9]%', @string)
WHILE @IncorrectCharLoc > 0
BEGIN
SET @string = STUFF(@string, @IncorrectCharLoc, 1, '')
SET @IncorrectCharLoc = PATINDEX('%[^0-9]%', @string)
END
SET @string = @string
RETURN @string
END
GO
创建该函数后,您可以像这样进行排序:
SELECT YourMixedColumn
FROM YourTable
ORDER BY CONVERT(INT, dbo.UDF_ParseNumericChars(YourMixedColumn))
可以用 Len 函数排序
create table #temp (id nvarchar(50) null)
select * from #temp order by LEN(id)