简体   繁体   English

通过升序字母数字字段SQL进行排序

[英]Order by ascending an alpha-numeric field SQL

I need to order by ascending an alpha-numeric field (SQL Server).The name of the field is OPE_libelle, you can see an extract from the database. 我需要通过升序一个字母数字字段(SQL Server)进行排序。该字段的名称为OPE_libelle,您可以从数据库中看到摘录。

这里

To do that I had created a function to keep the number only(FN_RESTRICT) but I would like to keep the number only when it's a simple OP ( OP 10 become 10, OP 4500 becomes 4500 ...) and for "OP 10 et OP 20" or "OP 10 7107" I keep like that. 为此,我创建了一个仅保留数字的函数(FN_RESTRICT),但我想仅在简单的OP(OP 10变为10,OP 4500变为4500 ...)时保留数字,并且对于“ OP 10等OP 20”或“ OP 10 7107”我一直这样。 I need to do that in my SQL request but don't modify the field in my database. 我需要在SQL请求中执行此操作,但不要修改数据库中的字段。

I tried this but the condition is not respected : 我尝试了这个,但条件没有得到遵守:

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

Error message: Conversion failed when converting the varchar value 'OP 10 7107' to data type int. 错误消息:将varchar值'OP 10 7107'转换为数据类型int时转换失败。

Or the length of 'OP 10 7107' is > 8 so I don't ask to convert it (it should have passed in the "else" case ...) If you have the other solution I am listening 或'OP 10 7107'的长度> 8,所以我不要求将其转换(它应该在“ else”情况下通过...)如果您有其他解决方案,我在听

FN_RESTRICT : 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

Have a look at the following. 看一下以下内容。 However, I used a simple substring - you will have to put yoour function call there instead: 但是,我使用了一个简单的子字符串-您将必须在其中放置函数调用:

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, '_')

The idea is to convert to int whatever is possible in a new column in your query, then order by this column and afterwards by the alphanumeric value. 想法是将查询中新列中可能的所有内容转换为int,然后按此列排序,然后按字母数字值排序。 Try replacing SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3) with your function call. 尝试用函数调用替换SUBSTRING(t.OPE_libelle, 4, LEN(t.OPE_libelle)-3)

Result: 结果:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM