在 SQL 服务器中将浮点数排序为自然数
sort float numbers as a natural numbers in SQL Server
好吧,我曾在 上针对 jquery 问过同样的问题,现在我的问题与 SQL 服务器查询相同 :) 但这次不是逗号分隔,这是数据库中的单独行,如
我用浮点数分隔行。
Name
K1.1
K1.10
K1.2
K3.1
K3.14
K3.5
我想像这样对浮点数进行排序,
Name
K1.1
K1.2
K1.10
K3.1
K3.5
K3.14
实际上在我的例子中,小数点后的数字将被视为自然数,因此 1.2 将被视为“2”,1.10 将被视为“10”,这就是为什么 1.2 将比 1.10 排在前面的原因。
您可以删除 'K',因为它几乎很常见,建议或示例对我来说非常有用,谢谢。
如果第一个数字前总是有一个字符且数字不大于 9,则此方法有效:
SELECT name
FROM YourTable
ORDER BY CAST(SUBSTRING(name,2,1) AS INT), --Get the number before dot
CAST(RIGHT(name,LEN(name)-CHARINDEX('.',name)) AS INT) --Get the number after the dot
较短的解决方案是这个:
Select Num
from yourtable
order by cast((Parsename(Num, 1) ) as Int)
也许,更多的口头表达,但应该可以做到
declare @source as table(num varchar(12));
insert into @source(num) values('K1.1'),('K1.10'),('K1.2'),('K3.1'),('K3.14'),('K3.5');
-- create helper table
with data as
(
select num,
cast(SUBSTRING(replace(num, 'K', ''), 1, CHARINDEX('.', num) - 2) as int) as [first],
cast(SUBSTRING(replace(num, 'K', ''), CHARINDEX('.', num), LEN(num)) as int) as [second]
from @source
)
-- Select and order accordingly
select num
from data
order by [first], [second]
sqlfiddle:
http://sqlfiddle.com/#!6/a9b06/2
您可以使用 PARSENAME
(更像是 hack)或字符串函数,如 CHARINDEX
、STUFF
、LEFT
等来实现此目的。
输入数据
;WITH CTE AS
(
SELECT 'K1.1' Name
UNION ALL SELECT 'K1.10'
UNION ALL SELECT 'K1.2'
UNION ALL SELECT 'K3.1'
UNION ALL SELECT 'K3.14'
UNION ALL SELECT 'K3.5'
)
使用PARSENAME
SELECT Name,PARSENAME(REPLACE(Name,'K',''),2),PARSENAME(REPLACE(Name,'K',''),1)
FROM CTE
ORDER BY CONVERT(INT,PARSENAME(REPLACE(Name,'K',''),2)),
CONVERT(INT,PARSENAME(REPLACE(Name,'K',''),1))
使用字符串函数
SELECT Name,LEFT(Name,CHARINDEX('.',Name) - 1), STUFF(Name,1,CHARINDEX('.',Name),'')
FROM CTE
ORDER BY CONVERT(INT,REPLACE((LEFT(Name,CHARINDEX('.',Name) - 1)),'K','')),
CONVERT(INT,STUFF(Name,1,CHARINDEX('.',Name),''))
输出
K1.1 K1 1
K1.2 K1 2
K1.10 K1 10
K3.1 K3 1
K3.5 K3 5
K3.14 K3 14
好吧,我曾在
我用浮点数分隔行。
Name
K1.1
K1.10
K1.2
K3.1
K3.14
K3.5
我想像这样对浮点数进行排序,
Name
K1.1
K1.2
K1.10
K3.1
K3.5
K3.14
实际上在我的例子中,小数点后的数字将被视为自然数,因此 1.2 将被视为“2”,1.10 将被视为“10”,这就是为什么 1.2 将比 1.10 排在前面的原因。
您可以删除 'K',因为它几乎很常见,建议或示例对我来说非常有用,谢谢。
如果第一个数字前总是有一个字符且数字不大于 9,则此方法有效:
SELECT name
FROM YourTable
ORDER BY CAST(SUBSTRING(name,2,1) AS INT), --Get the number before dot
CAST(RIGHT(name,LEN(name)-CHARINDEX('.',name)) AS INT) --Get the number after the dot
较短的解决方案是这个:
Select Num
from yourtable
order by cast((Parsename(Num, 1) ) as Int)
也许,更多的口头表达,但应该可以做到
declare @source as table(num varchar(12));
insert into @source(num) values('K1.1'),('K1.10'),('K1.2'),('K3.1'),('K3.14'),('K3.5');
-- create helper table
with data as
(
select num,
cast(SUBSTRING(replace(num, 'K', ''), 1, CHARINDEX('.', num) - 2) as int) as [first],
cast(SUBSTRING(replace(num, 'K', ''), CHARINDEX('.', num), LEN(num)) as int) as [second]
from @source
)
-- Select and order accordingly
select num
from data
order by [first], [second]
sqlfiddle: http://sqlfiddle.com/#!6/a9b06/2
您可以使用 PARSENAME
(更像是 hack)或字符串函数,如 CHARINDEX
、STUFF
、LEFT
等来实现此目的。
输入数据
;WITH CTE AS
(
SELECT 'K1.1' Name
UNION ALL SELECT 'K1.10'
UNION ALL SELECT 'K1.2'
UNION ALL SELECT 'K3.1'
UNION ALL SELECT 'K3.14'
UNION ALL SELECT 'K3.5'
)
使用PARSENAME
SELECT Name,PARSENAME(REPLACE(Name,'K',''),2),PARSENAME(REPLACE(Name,'K',''),1)
FROM CTE
ORDER BY CONVERT(INT,PARSENAME(REPLACE(Name,'K',''),2)),
CONVERT(INT,PARSENAME(REPLACE(Name,'K',''),1))
使用字符串函数
SELECT Name,LEFT(Name,CHARINDEX('.',Name) - 1), STUFF(Name,1,CHARINDEX('.',Name),'')
FROM CTE
ORDER BY CONVERT(INT,REPLACE((LEFT(Name,CHARINDEX('.',Name) - 1)),'K','')),
CONVERT(INT,STUFF(Name,1,CHARINDEX('.',Name),''))
输出
K1.1 K1 1
K1.2 K1 2
K1.10 K1 10
K3.1 K3 1
K3.5 K3 5
K3.14 K3 14