我有一个名为 TableName 的包含字母数字值的列,它几乎可以是任何短语,只要它是字母数字即可。
示例数据可以是(不一定是 3 个字母后跟数字)
AAA 1
AAB 2
AAC 3
AAB 10
AAC 12
AAB 12
如果我使用正常排序,例如ORDER BY TableName
这将变成
AAA 1
AAB 10
AAB 12
AAB 2
AAC 12
AAC 3
我想要完成的是
AAA 1
AAB 2
AAB 10
AAB 12
AAC 3
AAC 12
我想让你知道这个领域可以是任何东西 即
ABC123MAS3482
KASJ19LKA
213LKS23
只是为了让您知道该字段没有格式。 唯一的规则是它是字母数字。
我希望你们能帮助我掌握 SQL 方面的高级知识。
我正在使用 SQL Server 2008 R2
以不同的方式对字母数字列进行排序:
CREATE TABLE dbo.AlphnumericTable (AlphnumericColumn varchar(50) NULL)
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('3')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('AB1')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('A1')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('B2')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('A11')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('B20')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('B21')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('AB10')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('B3')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('AB100')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('2')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('1')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('B32')
INSERT INTO dbo.AlphnumericTable (AlphnumericColumn) VALUES ('11')
SELECT AlphnumericColumn FROM dbo.AlphnumericTable
--Show normal Sort
SELECT AlphnumericColumn FROM dbo.AlphnumericTable ORDER BY AlphnumericColumn
--Show AlphaNumberic Sort
SELECT AlphnumericColumn FROM dbo.AlphnumericTable ORDER BY LEFT(AlphnumericColumn,PATINDEX('%[0-9]%',AlphnumericColumn)-1), -- alphabetical sort
CONVERT(INT,SUBSTRING(AlphnumericColumn,PATINDEX('%[0-9]%',AlphnumericColumn),LEN(AlphnumericColumn))) -- numerical sort
--cleanup our work
DROP Table dbo.AlphnumericTable
我很确定这不会太容易完成。
你的陈述
I'd like you to know that this field COULD be ANYTHING i.e.
几乎杀死了它,否则可以将字母和数字值拆分为两列,或者让它们被某种字符串函数拆分。
但是这样我能看到的唯一出路是:
编写您自己的函数,返回一个可以排序的数值。 然后你就可以像这样使用它:
SELECT AlphaNumericValue FROM ValuesTable ORDER BY dbo.GETSORTVALUE(AlphaNumericValue)
这可能是此类功能的虚拟主体:
CREATE FUNCTION dbo.GETSORTVALUE(@value NVARCHAR)
RETURNS INT
BEGIN
DECLARE @dummyValue INT = LEN(@value)
-- do something with your string here to get a sorting number
RETURN @dummyValue
END
由于列中的值可能是
anything
,因此您需要首先进行良好的排序,然后应将其包含在该函数中。
例如,您尚未定义在这种情况下如何排序:
你说
AAB 2
应该出现在AAB 10
之前,但是AA2B
和AA10B
呢?
一旦定义了这个,您的自定义逻辑就应该进入该函数。
编写一个函数,在每个数字子串前面插入一个前导零,并按其排序。您可能希望将其存储在列中,并在数据发生变化时进行更新。
创建这个函数
create function dbo.udf_ExpandDigits(@src varchar(1024), @plen int, @letter
char(1))
returns varchar(max)
as
begin
if @plen >= 100
return @src;
declare @p int, @p2 int, @num varchar(100);
declare @ret_val varchar(max)='';
if (PATINDEX('%[0-9]%', @src) =0 )
set @ret_val = @src;
else
begin
set @p = patindex('%[0-9]%', @src);
while(@p > 0)
begin
set @p2=patindex('%[^0-9]%', substring(@src, @p, 1000))
if (@p2 > 0)
begin
set @num=substring(@src, @p, @p2-1);
set @ret_val += left(@src, @p-1) + case when len(@num) < @plen then right(replicate(@letter, @plen) + @num, @plen) else @num end; ;
set @src = substring(@src, @p+@p2-1, len(@src));
set @p = patindex('%[0-9]%', @src);
end
else
begin
set @num = substring(@src, @p, len(@src));
set @ret_val += left(@src, @p-1)+ case when len(@num) < @plen then right(replicate(@letter, @plen) + @num, @plen) else @num end;
set @src ='';
break;
end
end -- while (@p > 0)
if len(@src) > 0
set @ret_val += @src;
end -- else
return @ret_val;
end -- function
并像示例一样使用它:
SELECT
your_column ,
Formatted_Code=dbo.udf_ExpandDigits(your_column, 3, '0')
FROM
your_table
order by
Formatted_Code