sql - MS SQL Server 获取逗号之间的值

标签 sql sql-server sql-server-2008 tsql

我在 Table1 中有一个列,其中包含用逗号分隔的字符串:

Id Val
1  ,4
2  ,3,1,0
3  NULL
4  ,5,2

有没有一种简单的方法可以拆分并从该列中获取任何值, 例如

SELECT Value(1) FROM Table1 应该得到

Id Val
1  4
2  3
3  NULL
4  5

SELECT Value(2) FROM Table1 应该得到

Id Val
1  NULL
2  1
3  NULL
4  2

谢谢!

最佳答案

在列中存储逗号分隔值总是很痛苦,请考虑更改表结构

要完成此操作,请创建一个分割字符串函数。这是将字符串拆分为单独行的最佳方法之一。引用自http://www.sqlservercentral.com/articles/Tally+Table/72993/

CREATE FUNCTION [dbo].[DelimitedSplit8K]
        (@pString VARCHAR(8000), @pDelimiter CHAR(1))
RETURNS TABLE WITH SCHEMABINDING AS
 RETURN
--===== "Inline" CTE Driven "Tally Table" produces values from 0 up to 10,000...
     -- enough to cover NVARCHAR(4000)
  WITH E1(N) AS (
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
                 SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
                ),                          --10E+1 or 10 rows
       E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
       E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
 cteTally(N) AS (--==== This provides the "base" CTE and limits the number of rows right up front
                     -- for both a performance gain and prevention of accidental "overruns"
                 SELECT TOP (ISNULL(DATALENGTH(@pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
                ),
cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
                 SELECT 1 UNION ALL
                 SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
                ),
cteLen(N1,L1) AS(--==== Return start and length (for use in substring)
                 SELECT s.N1,
                        ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000)
                   FROM cteStart s
                )
--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
 SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
        Item       = SUBSTRING(@pString, l.N1, l.L1)
   FROM cteLen l

调用函数

SELECT *
FROM   yourtable
       CROSS apply (SELECT CASE WHEN LEFT(val, 1) = ',' THEN Stuff(val, 1, 1, '') ELSE val END) cs (cleanedval)
       CROSS apply [dbo].[Delimitedsplit8k](cs.cleanedval, ',')
WHERE  ItemNumber = 1

SELECT *
FROM   yourtable
       CROSS apply (SELECT CASE WHEN LEFT(val, 1) = ',' THEN Stuff(val, 1, 1, '') ELSE val END) cs (cleanedval)
       CROSS apply [dbo].[Delimitedsplit8k](cs.cleanedval, ',')
WHERE  ItemNumber = 2 

关于sql - MS SQL Server 获取逗号之间的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48240404/

相关文章:

sql - 将一条记录分成多条

javascript - 使用 PHP 抓取 SQL 数据,然后将数组发送到 Javascript

sql-server - SQL Server - 选择并连接父子记录、数据透视和分组

sql - 获取 MS SQL Server 2008 的连接字符串

.net - ADO.NET 超时但在 SSMS 中工作正常

python - 使用链接的 Django 模型快速计数

sql - Access 中日期时间的平均值

sql-server - 查询将多行变成单行

c# - ssis 脚本任务中的字符数据中不允许使用 ']]>'

sql-server-2008 - 在 SQL Server 中使用合并更新第三个表