【问题标题】:How to get value using split string in SQL Server 2019如何在 SQL Server 2019 中使用拆分字符串获取值
【发布时间】:2021-01-17 10:01:52
【问题描述】:

我在下面的列中有值(空格分隔的字符串)

1 4 7 5
4 5
1 4
1 3 4 

我只需要1是3次,3是1次,4是4次,5是2次,7是1次。

如下:

Value| count
-----+-------
 1   |   3 
 3   |   1 
 4   |   4 
 5   |   2 
 7   |   1 

我试过这样:

SELECT value  
FROM [dbo].tbl  
CROSS APPLY STRING_SPLIT((SELECT DisCode FROM tbl), ' ');

但我得到一个错误

无效的对象名称“STRING_SPLIT”

我尝试过: String_split function is not splitting delimiters in SQL Server 2019 但没有得到任何解决方案。

有人问最低兼容级别,但是我无法按服务器级别降级,因为它是一个正在运行的在线服务器。('STRING_SPLIT' is not a recognized built-in function name

请给我一个可能的解决方案。

【问题讨论】:

  • STING_SPLITSQL Server 2019 中可用。您的兼容性级别必须设置为更早的版本。 STRING_SPLIT 应可从 SQL Server 2016 / 兼容级别 130 获得
  • 你运行的是什么版本select @@version? @Squirrel STING_SPLIT 肯定可用,STRING_SPLIT 从 2016 年开始可用
  • 我的版本是:Microsoft SQL Server 2019 (RTM-GDR)。我无法降级兼容级别。
  • @Charlieface 哈哈。错别字
  • 我们不是要求您降级compatibility level,而是如果您想使用STRING_SPLIT(),请将其更改为最低130

标签: sql sql-server sql-server-2019


【解决方案1】:

STING_SPLIT 在SQL Server 2019 中可用。您的兼容性级别必须设置为更早的版本。 STRING_SPLIT 应该从 SQL Server 2016/兼容级别 130 起可用。

你的查询应该是

SELECT  value, count(*)
FROM    tbl 
        CROSS APPLY STRING_SPLIT (DisCode, ' ')
GROUP BY value

STRING_SPLIT (Transact-SQL)

【讨论】:

  • 还是一样:无效的对象名称'STRING_SPLIT'。
  • 您的兼容级别是多少?
【解决方案2】:

STRING_SPLIT() 从 SQL Server 2016 开始可用,这意味着它需要兼容级别 130 或更高(请参阅documentation)。

在 SQL Server 2019 上运行的数据库可以以各种兼容级别运行,甚至低于 130。您可以使用以下方法检查数据库的兼容性级别:

SELECT compatibility_level  
FROM sys.databases
WHERE name = db_name();

如果小于 130,那么您将无法访问该功能,除非您更改兼容性或创建具有更高兼容性级别的新数据库。

【讨论】:

    【解决方案3】:

    在 SQL 2016 之前,一种拆分字符串的方法是/曾经是使用 'Tally' function or 'numbers' table 方法。在此代码中,CTE 'numbers_cte' 包含 20 行。外部查询使用 CROSS JOIN 创建最多 400 (20^2) 行(如果需要更多行,则根据需要添加更多 CROSS JOINs)。使用行目标 (SELECT TOP(n)) 意味着永远不会生成未使用的行,因此查询非常有效。像这样的

    declare @txtTable   table(txt       varchar(50) not null)
    
    insert @txtTable(txt) values 
    ('1 4 7 5'),
    ('4 5'),
    ('1 4'),
    ('1 3 4');
    
    with numbers_cte(n) as (
        select * from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
                              (11),(12),(13),(14),(15),(16),(17),(18),(19),(20)) v(n))
    select v.chr, count(*) as char_count
    from @txtTable t
         cross apply (select top(len(t.txt)) row_number() over (order by (select null)) as N
                      from numbers_cte n1
                           cross join numbers_cte n2) fn
         cross apply (values (substring(t.txt, N, 1))) v(chr)
    where
      v.chr <> ' '
    group by v.chr;
    
    chr char_count
    1   3
    3   1
    4   4
    5   2
    7   1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-14
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      相关资源
      最近更新 更多