Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
按以数字和字符串开头的列对SQL server表进行数字排序_Sql_Sql Server_Tsql_Sql Order By - Fatal编程技术网

按以数字和字符串开头的列对SQL server表进行数字排序

按以数字和字符串开头的列对SQL server表进行数字排序,sql,sql-server,tsql,sql-order-by,Sql,Sql Server,Tsql,Sql Order By,我将按包含以下数据的列对SQL server表进行排序: 2.5.1 Sonstiges 1.1.1 Pflegstandards 5.1.7 Arbeitsgemeinschaften 1.2.1 Anforderungen 2.4.5 Betriebsarzt B Kernprozesse 1.1.1.4 Umgang mit 2.3.3 Kardiologie ...... 正如您所看到的,大多数记录都以数字开头,但也有一些记录以字符串开头。我使用以下查询来涵盖这两种情况: SELECT

我将按包含以下数据的列对SQL server表进行排序:

2.5.1 Sonstiges
1.1.1 Pflegstandards
5.1.7 Arbeitsgemeinschaften
1.2.1 Anforderungen
2.4.5 Betriebsarzt
B Kernprozesse
1.1.1.4 Umgang mit
2.3.3 Kardiologie
......
正如您所看到的,大多数记录都以数字开头,但也有一些记录以字符串开头。我使用以下查询来涵盖这两种情况:

SELECT * from DocumentCategories 
  order by
    case IsNumeric(replace( LEFT(name, CHARINDEX(' ', name)),'.','')) 
        when 0 then name
        when 1 then cast(replace( LEFT(name, CHARINDEX(' ', name)),'.','') as int)
    end
name
=====================
B Kernprozesse
1.1.1 Pflegstandards
1.2.1 Anforderungen
2.3.3 Kardiologie
2.4.5 Betriebsarzt
2.5.1 Sonstiges
5.1.7 Arbeitsgemeinschaften
1.1.1.4 Umgang mit
但是我得到一个关于varchar到int转换的错误(因为记录包含“B Kernprozesse”)。那么case/when在这里扮演什么角色?我错过什么了吗

我希望输出如下所示:

B Kernprozesse
1.1.1 Pflegstandards
1.2.1 Anforderungen
2.3.3 Kardiologie
2.4.5 Betriebsarzt
2.5.1 Sonstiges
5.1.7 Arbeitsgemeinschaften
1.1.1.4 Umgang mit

……你只是在找我吗

SELECT *
FROM (
      VALUES
      ('2.5.1 Sonstiges'),
      ('1.1.1 Pflegstandards'),
      ('5.1.7 Arbeitsgemeinschaften'),
      ('1.2.1 Anforderungen'),
      ('2.4.5 Betriebsarzt'),
      ('B Kernprozesse'),
      ('1.1.1.4 Umgang mit'),
      ('2.3.3 Kardiologie')
     ) T(Str)
ORDER BY
CASE WHEN TRY_CAST(LEFT(Str, 1) AS INT) IS NOT NULL
     THEN 0
     ELSE 1
END
WITH A AS
(
  SELECT *, ((LEN(Str) - LEN(REPLACE(Str, '.', ''))) * 2) + 1 N
  FROM (
        VALUES
        ('2.5.1 Sonstiges'),
        ('1.1.1 Pflegstandards'),
        ('5.1.7 Arbeitsgemeinschaften'),
        ('1.2.1 Anforderungen'),
        ('2.4.5 Betriebsarzt'),
        ('B Kernprozesse'),
        ('1.1.1.4 Umgang mit'),
        ('2.3.3 Kardiologie')
       ) T(Str)
)
SELECT *
FROM A
ORDER BY CASE WHEN TRY_CAST(REPLACE(LEFT(Str, N), '.', '') AS INT) IS NULL
              THEN 0
              ELSE CAST(REPLACE(LEFT(Str, N), '.', '') AS INT)
         END
哪个会回来

+-----------------------------+
|             Str             |
+-----------------------------+
| 1.1.1 Pflegstandards        |
| 5.1.7 Arbeitsgemeinschaften |
| 1.2.1 Anforderungen         |
| 2.4.5 Betriebsarzt          |
| 2.3.3 Kardiologie           |
| 1.1.1.4 Umgang mit          |
| 2.5.1 Sonstiges             |
| B Kernprozesse              |
+-----------------------------+

更新:

根据你问题的最新更新,你正在寻找

SELECT *
FROM (
      VALUES
      ('2.5.1 Sonstiges'),
      ('1.1.1 Pflegstandards'),
      ('5.1.7 Arbeitsgemeinschaften'),
      ('1.2.1 Anforderungen'),
      ('2.4.5 Betriebsarzt'),
      ('B Kernprozesse'),
      ('1.1.1.4 Umgang mit'),
      ('2.3.3 Kardiologie')
     ) T(Str)
ORDER BY
CASE WHEN TRY_CAST(LEFT(Str, 1) AS INT) IS NOT NULL
     THEN 0
     ELSE 1
END
WITH A AS
(
  SELECT *, ((LEN(Str) - LEN(REPLACE(Str, '.', ''))) * 2) + 1 N
  FROM (
        VALUES
        ('2.5.1 Sonstiges'),
        ('1.1.1 Pflegstandards'),
        ('5.1.7 Arbeitsgemeinschaften'),
        ('1.2.1 Anforderungen'),
        ('2.4.5 Betriebsarzt'),
        ('B Kernprozesse'),
        ('1.1.1.4 Umgang mit'),
        ('2.3.3 Kardiologie')
       ) T(Str)
)
SELECT *
FROM A
ORDER BY CASE WHEN TRY_CAST(REPLACE(LEFT(Str, N), '.', '') AS INT) IS NULL
              THEN 0
              ELSE CAST(REPLACE(LEFT(Str, N), '.', '') AS INT)
         END
返回:

+-----------------------------+---+
|             Str             | N |
+-----------------------------+---+
| B Kernprozesse              | 1 |
| 1.1.1 Pflegstandards        | 5 |
| 1.2.1 Anforderungen         | 5 |
| 2.3.3 Kardiologie           | 5 |
| 2.4.5 Betriebsarzt          | 5 |
| 2.5.1 Sonstiges             | 5 |
| 5.1.7 Arbeitsgemeinschaften | 5 |
| 1.1.1.4 Umgang mit          | 7 |
+-----------------------------+---+

如评论中所述,您可以像这样使用
TRY\u CAST

SELECT * FROM @DocumentCategories 
  ORDER BY
    CASE WHEN TRY_CAST(replace( LEFT(name, CHARINDEX(' ', name)),'.','') AS INT) IS NULL
        THEN 0 
        ELSE cast(replace( LEFT(name, CHARINDEX(' ', name)),'.','') as int) 
    END
如果您在2012版之前的SQL_SERVER环境中,则可以使用
ISNUMERIC
并获得相同的结果:

SELECT * FROM @DocumentCategories 
  ORDER BY
    CASE WHEN ISNUMERIC(replace( LEFT(name, CHARINDEX(' ', name)),'.','')) = 0 
        THEN 0 
        ELSE cast(replace( LEFT(name, CHARINDEX(' ', name)),'.','') as int) 
    END 
以下是两种情况下的结果:

SELECT * from DocumentCategories 
  order by
    case IsNumeric(replace( LEFT(name, CHARINDEX(' ', name)),'.','')) 
        when 0 then name
        when 1 then cast(replace( LEFT(name, CHARINDEX(' ', name)),'.','') as int)
    end
name
=====================
B Kernprozesse
1.1.1 Pflegstandards
1.2.1 Anforderungen
2.3.3 Kardiologie
2.4.5 Betriebsarzt
2.5.1 Sonstiges
5.1.7 Arbeitsgemeinschaften
1.1.1.4 Umgang mit

不要使用
ISNUMERIC()
它有一些问题。
B Kernprozesse
是否可以像
B Kernprozesse1.2.3
ISNUMERIC
是一个糟糕的函数,如果我诚实的话。如果确实要测试字符串是否为数值,请使用
TRY\u CONVERT
TRY\u CAST
。此外,这里的问题是,您从
大小写表达式返回了两种不同的数据类型
[name]
显然是一个
varchar
,但您的另一个表达式正在转换为
int
。因此,
[name]
也被强制转换为
int
,这是由于数据类型前置,因此转换失败。您预期的输出是什么?请添加示例输出数据。
1.1.1.4
1.1.2
相比如何?现在,您的替换将这变成
1114 vs 112
。预期输出会有帮助。如更新问题中所述,1.1.1.4应该是最后一个,1.2.1应该紧跟在1.1之后。1@Ali_dotNet您如何确定是否有3个努伯?5.4.或者它是静态的?正如你在我的查询中看到的,我使用replace来删除“.”,事实上数字的格式可能是1、1.1、1.1.1或1.1.1。我认为这个查询删除了前导数字(如果存在的话),然后按结果名称排序,我希望它按数字排序(当然是在删除“.”之后)@Ali_dotNet Yup,我知道你想做什么,并相应地更新答案。谢谢,但如果我还有一些以字符串开头的记录呢?我怎样才能把它们也分类呢?这个0在这里意味着什么?@Ali_dotNet你不能轻易地将数字和字母排序在一起。0表示如果
案例
为真,则使用提供的值(本例中为0)。使用0是因为它比其他可能的整数低-如果
大小写
为true(名称不是数字/无法转换),则将其置于列表顶部。它的作用是将所有非数值赋值为0,然后,
orderby
比较
0和0
,并声明一个平局。希望这是有意义的。这几乎就是我想要的,谢谢你的描述性评论:)@Ali_dotNet我建议在评论中为你的问题打开一个新的问题。我不知道这是否可能/如何可能,但我相信还有其他想法,你可以如何实现这一点。如果值不是数字,则尝试按字母排序,如果值是数字,则尝试按数字排序。祝你好运。像
'1.12.123 Eins'
'11.21.22 Zwei'
这样的值是如何排序的?