我有一个VARCHAR
列中SQL Server 2000
数据库可以包含字母或数字。 这取决于应用程序如何在前端为客户进行配置。
当它包含数字,我希望它是数字顺序排序,例如为“1”,“2”,“10”,而不是“1”,“10”,“2”。 只包含字母字段,或字母和数字(如“A1”)可以按字母顺序为正常进行排序。 例如,这将是可接受的排序顺序。
1
2
10
A
B
B1
什么是实现这一目标的最佳途径?
我有一个VARCHAR
列中SQL Server 2000
数据库可以包含字母或数字。 这取决于应用程序如何在前端为客户进行配置。
当它包含数字,我希望它是数字顺序排序,例如为“1”,“2”,“10”,而不是“1”,“10”,“2”。 只包含字母字段,或字母和数字(如“A1”)可以按字母顺序为正常进行排序。 例如,这将是可接受的排序顺序。
1
2
10
A
B
B1
什么是实现这一目标的最佳途径?
一个可能的解决方案是垫在前面一个字符的数字值,使得所有都是相同的字符串的长度。
下面是使用这种方法的例子:
select MyColumn
from MyTable
order by
case IsNumeric(MyColumn)
when 1 then Replicate('0', 100 - Len(MyColumn)) + MyColumn
else MyColumn
end
的100
应与该列的实际长度来代替。
有几种可能的方式来做到这一点。
其中之一是
SELECT
...
ORDER BY
CASE
WHEN ISNUMERIC(value) = 1 THEN CONVERT(INT, value)
ELSE 9999999 -- or something huge
END,
value
在ORDER BY的第一部分的一切转换为int(与非NUMERICS巨大的价值,最后排序),则最后部分需要alphabetics的照顾。
请注意,此查询的性能可能至少是适度可怕的大量数据。
select
Field1, Field2...
from
Table1
order by
isnumeric(Field1) desc,
case when isnumeric(Field1) = 1 then cast(Field1 as int) else null end,
Field1
这将在你在你的问题下达了命令返回值。
性能不会与所有铸造事情太大了,所以另一种方法是到另一列添加到您在疑问,先列排序存储数据的整数副本,然后表。 这显然需要一些改变,在表中插入或更新数据的逻辑,来填充两列。 要么,或把一个触发器在桌子上以填充第二列每当数据被插入或更新。
SELECT *, CONVERT(int, your_column) AS your_column_int
FROM your_table
ORDER BY your_column_int
要么
SELECT *, CAST(your_column AS int) AS your_column_int
FROM your_table
ORDER BY your_column_int
两者都是相当便携,我认为。
我解决它以非常简单的方式,在“命令”部分写入该
ORDER BY (
sr.codice +0
)
ASC
这似乎很好地工作,其实我有以下分类:
16079 Customer X
016082 Customer Y
16413 Customer Z
所以, 0
前面16082
是正确的考虑。
你可以随时将您的VARCHAR列到BIGINT的整数可能太短...
select cast([yourvarchar] as BIGINT)
但要始终关心字母字符
where ISNUMERIC([yourvarchar] +'e0') = 1
在+“E0”来自http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/isnumeric-isint-isnumber
这将导致您的发言
SELECT
*
FROM
Table
ORDER BY
ISNUMERIC([yourvarchar] +'e0') DESC
, LEN([yourvarchar]) ASC
第一排序列将会把数字放在上面。 第二种类由长度,因此10将preceed 0001(这是愚蠢的?)
这导致了第二个版本:
SELECT
*
FROM
Table
ORDER BY
ISNUMERIC([yourvarchar] +'e0') DESC
, RIGHT('00000000000000000000'+[yourvarchar], 20) ASC
第二列现在得到正确补齐“0”,所以自然排序把整数用正确的顺序前导零(0,01,10,0100 ...)(正确的!) - 但所有阿尔法将与“0”来增强-chars(性能)
所以第三个版本:
SELECT
*
FROM
Table
ORDER BY
ISNUMERIC([yourvarchar] +'e0') DESC
, CASE WHEN ISNUMERIC([yourvarchar] +'e0') = 1
THEN RIGHT('00000000000000000000' + [yourvarchar], 20) ASC
ELSE LTRIM(RTRIM([yourvarchar]))
END ASC
现在的数字首先得到填充有个“0'字符(当然,长度20可以增强) - 这种种数字对的 - 阿尔法只得到修整
这似乎工作:
select your_column
from your_table
order by
case when isnumeric(your_column) = 1 then your_column else 999999999 end,
your_column
SELECT FIELD FROM TABLE
ORDER BY
isnumeric(FIELD) desc,
CASE ISNUMERIC(test)
WHEN 1 THEN CAST(CAST(test AS MONEY) AS INT)
ELSE NULL
END,
FIELD
按照这个链接 ,你需要转换为MONEY则INT避免订货“$”作为一个数字。
这种查询是对你有帮助。 在这个查询中,列有数据类型为varchar布置良好的order.For例 - 此列的数据是: - G1,G34,G10,G3。 因此,在运行此查询后,看到的结果: - G1,G10,G3,G34。
SELECT *,
(CASE WHEN ISNUMERIC(column_name) = 1 THEN 0 ELSE 1 END) IsNum
FROM table_name
ORDER BY IsNum, LEN(column_name), column_name;
这可能会帮助你,我曾经尝试这样做时,我得到了同样的问题。
SELECT * FROM tab ORDER BY IIF(TRY_CAST(val AS INT) IS NULL, 1, 0),TRY_CAST(val AS INT);
SELECT *,
ROW_NUMBER()OVER(ORDER BY CASE WHEN ISNUMERIC (ID)=1 THEN CONVERT(NUMERIC(20,2),SUBSTRING(Id, PATINDEX('%[0-9]%', Id), LEN(Id)))END DESC)Rn ---- numerical
FROM
(
SELECT '1'Id UNION ALL
SELECT '25.20' Id UNION ALL
SELECT 'A115' Id UNION ALL
SELECT '2541' Id UNION ALL
SELECT '571.50' Id UNION ALL
SELECT '67' Id UNION ALL
SELECT 'B48' Id UNION ALL
SELECT '500' Id UNION ALL
SELECT '147.54' Id UNION ALL
SELECT 'A-100' Id
)A
ORDER BY
CASE WHEN ISNUMERIC (ID)=0 /* alphabetical sort */
THEN CASE WHEN PATINDEX('%[0-9]%', Id)=0
THEN LEFT(Id,PATINDEX('%[0-9]%',Id))
ELSE LEFT(Id,PATINDEX('%[0-9]%',Id)-1)
END
END DESC