按升序排列字母数字字段 SQL
Order by ascending an alpha-numeric field SQL
我需要按字母数字字段(SQL服务器)升序排序。字段名称是OPE_libelle,你可以从数据库中看到一个摘录。
为此,我创建了一个仅保留数字的函数(FN_RESTRICT),但我只想在它是一个简单的 OP 时保留该数字(OP 10 变为 10,OP 4500 变为 4500。 ..) 和 "OP 10 et OP 20" 或 "OP 10 7107" 我保持这样。我需要在我的 SQL 请求中这样做,但不要修改我的数据库中的字段。
我试过了,但条件没有得到遵守:
SELECT CASE
WHEN LEN(OPE_libelle)<= 8 THEN
CAST(dbo.FN_RESTRICT(OPE_libelle, '0123456789') AS INTEGER)
ELSE
OPE_libelle
END
FROM TR_OPERATION ORDER BY OPE_libelle
错误消息:将 varchar 值 'OP 10 7107' 转换为数据类型 int 时转换失败。
或者 'OP 10 7107' 的长度 > 8 所以我不要求转换它(它应该在 "else" 的情况下通过......)如果你有其他解决方案我正在听
FN_RESTRICT :
/****************************************************************************/
-- purge de caractères indésirables
/****************************************************************************/
-- exemple : FN_RESTRICT('à Paris...?', 'abcdefghijklmnopqrstuvwxyz') => 'aris'
CREATE FUNCTION FN_RESTRICT (@IN VARCHAR (8000),
@CHARSOK VARCHAR(256))
RETURNS VARCHAR (8000)
AS
BEGIN
-- effets de bord
IF @IN IS NULL
RETURN NULL
IF @CHARSOK IS NULL
RETURN NULL
IF LEN(@IN) = 0
RETURN @IN
-- initialisation
DECLARE @I INTEGER
DECLARE @OUT VARCHAR(8000)
SET @OUT = ''
-- lecture caractère par caractère
SET @I =1
WHILE @I <= LEN(@IN)
BEGIN
IF PATINDEX('%' + SUBSTRING(@IN, @I, 1)+ '%', @CHARSOK) > 0
SET @OUT = @OUT + SUBSTRING(@IN, @I, 1)
SET @I = @I + 1
END
RETURN @OUT
END
GO
看看下面的内容。但是,我使用了一个简单的子字符串 - 你必须将你的函数调用放在那里:
DECLARE @t TABLE(
OPE_libelle VARCHAR(100)
);
INSERT INTO @t VALUES ('OF 5030'), ('OF 5040'), ('OP 05'), ('OP 10'), ('OP 10 7107'), ('OP 10 et 20');
SELECT t.OPE_libelle
,CASE WHEN ISNUMERIC(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)) = 1 THEN CAST(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3) AS INT) ELSE NULL END AS OPE_libelle_Num
,CASE WHEN ISNUMERIC(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)) = 1 THEN CAST(NULL AS VARCHAR(1000)) ELSE t.OPE_libelle END AS OPE_libelle_Char
FROM @t AS t
ORDER BY ISNULL(CASE WHEN ISNUMERIC(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)) = 1 THEN CAST(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3) AS INT) ELSE NULL END, 999999999)
,ISNULL(CASE WHEN ISNUMERIC(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)) = 1 THEN CAST(NULL AS VARCHAR(1000)) ELSE t.OPE_libelle END, '_')
我们的想法是将查询中新列中可能的任何内容转换为 int,然后按此列排序,然后按字母数字值排序。尝试用您的函数调用替换 SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)
。
结果:
OPE_libelle OPE_libelle_Num OPE_libelle_Char
OP 05 5 NULL
OP 10 10 NULL
OF 5030 5030 NULL
OF 5040 5040 NULL
OP 10 7107 NULL OP 10 7107
OP 10 et 20 NULL OP 10 et 20
我需要按字母数字字段(SQL服务器)升序排序。字段名称是OPE_libelle,你可以从数据库中看到一个摘录。
为此,我创建了一个仅保留数字的函数(FN_RESTRICT),但我只想在它是一个简单的 OP 时保留该数字(OP 10 变为 10,OP 4500 变为 4500。 ..) 和 "OP 10 et OP 20" 或 "OP 10 7107" 我保持这样。我需要在我的 SQL 请求中这样做,但不要修改我的数据库中的字段。
我试过了,但条件没有得到遵守:
SELECT CASE
WHEN LEN(OPE_libelle)<= 8 THEN
CAST(dbo.FN_RESTRICT(OPE_libelle, '0123456789') AS INTEGER)
ELSE
OPE_libelle
END
FROM TR_OPERATION ORDER BY OPE_libelle
错误消息:将 varchar 值 'OP 10 7107' 转换为数据类型 int 时转换失败。
或者 'OP 10 7107' 的长度 > 8 所以我不要求转换它(它应该在 "else" 的情况下通过......)如果你有其他解决方案我正在听
FN_RESTRICT :
/****************************************************************************/
-- purge de caractères indésirables
/****************************************************************************/
-- exemple : FN_RESTRICT('à Paris...?', 'abcdefghijklmnopqrstuvwxyz') => 'aris'
CREATE FUNCTION FN_RESTRICT (@IN VARCHAR (8000),
@CHARSOK VARCHAR(256))
RETURNS VARCHAR (8000)
AS
BEGIN
-- effets de bord
IF @IN IS NULL
RETURN NULL
IF @CHARSOK IS NULL
RETURN NULL
IF LEN(@IN) = 0
RETURN @IN
-- initialisation
DECLARE @I INTEGER
DECLARE @OUT VARCHAR(8000)
SET @OUT = ''
-- lecture caractère par caractère
SET @I =1
WHILE @I <= LEN(@IN)
BEGIN
IF PATINDEX('%' + SUBSTRING(@IN, @I, 1)+ '%', @CHARSOK) > 0
SET @OUT = @OUT + SUBSTRING(@IN, @I, 1)
SET @I = @I + 1
END
RETURN @OUT
END
GO
看看下面的内容。但是,我使用了一个简单的子字符串 - 你必须将你的函数调用放在那里:
DECLARE @t TABLE(
OPE_libelle VARCHAR(100)
);
INSERT INTO @t VALUES ('OF 5030'), ('OF 5040'), ('OP 05'), ('OP 10'), ('OP 10 7107'), ('OP 10 et 20');
SELECT t.OPE_libelle
,CASE WHEN ISNUMERIC(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)) = 1 THEN CAST(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3) AS INT) ELSE NULL END AS OPE_libelle_Num
,CASE WHEN ISNUMERIC(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)) = 1 THEN CAST(NULL AS VARCHAR(1000)) ELSE t.OPE_libelle END AS OPE_libelle_Char
FROM @t AS t
ORDER BY ISNULL(CASE WHEN ISNUMERIC(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)) = 1 THEN CAST(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3) AS INT) ELSE NULL END, 999999999)
,ISNULL(CASE WHEN ISNUMERIC(SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)) = 1 THEN CAST(NULL AS VARCHAR(1000)) ELSE t.OPE_libelle END, '_')
我们的想法是将查询中新列中可能的任何内容转换为 int,然后按此列排序,然后按字母数字值排序。尝试用您的函数调用替换 SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)
。
结果:
OPE_libelle OPE_libelle_Num OPE_libelle_Char
OP 05 5 NULL
OP 10 10 NULL
OF 5030 5030 NULL
OF 5040 5040 NULL
OP 10 7107 NULL OP 10 7107
OP 10 et 20 NULL OP 10 et 20