递归 SQL 将 CSV 拆分为表行

发布于 2024-11-07 17:21:13 字数 983 浏览 0 评论 0原文

在解决了一个不同的问题后,我偶然发现了递归 CTE,从表面上看,这似乎是解决“将 csv 拆分为表行”问题的相当简单的方法。

我把这个例子放在一起

DECLARE @InputString varchar(255) = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z'

SELECT @InputString = @InputString + ','
;
with MyCTE(x,y)
as 
(
    SELECT 
        x = SUBSTRING(@InputString,0,PATINDEX('%,%',@InputString)),
        y = SUBSTRING(@InputString,PATINDEX('%,%',@InputString)+1,LEN(@InputString))
    UNION ALL
        SELECT 
            x = SUBSTRING(y,0,PATINDEX('%,%',y)),
            y = SUBSTRING(y,PATINDEX('%,%',y)+1,LEN(y))
        FROM 
            MyCTE 
        WHERE
                SUBSTRING(y,PATINDEX('%,%',y)+1,LEN(y)) <> '' OR 
            SUBSTRING(y,0,PATINDEX('%,%',y)) <> ''
)
SELECT x FROM MyCTE
OPTION (MAXRECURSION 2000);
GO

这真的是一个坏主意吗?像这样的递归查询在 SQL 中的开销是多少,这种方法有哪些潜在的陷阱。

顺便说一句,我认为这个想法/技术可能可以用来解决这个其他问题。

After working on a different question here on SO, I stumbled across recursive CTEs which would on the surface seem a fairly easy way to solve the "Split a csv to table rows" problem.

I put this example together

DECLARE @InputString varchar(255) = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z'

SELECT @InputString = @InputString + ','
;
with MyCTE(x,y)
as 
(
    SELECT 
        x = SUBSTRING(@InputString,0,PATINDEX('%,%',@InputString)),
        y = SUBSTRING(@InputString,PATINDEX('%,%',@InputString)+1,LEN(@InputString))
    UNION ALL
        SELECT 
            x = SUBSTRING(y,0,PATINDEX('%,%',y)),
            y = SUBSTRING(y,PATINDEX('%,%',y)+1,LEN(y))
        FROM 
            MyCTE 
        WHERE
                SUBSTRING(y,PATINDEX('%,%',y)+1,LEN(y)) <> '' OR 
            SUBSTRING(y,0,PATINDEX('%,%',y)) <> ''
)
SELECT x FROM MyCTE
OPTION (MAXRECURSION 2000);
GO

Is this really a bad idea? What is the overhead in SQL for recursive queries like this, and what are the potential pitfalls for this kind of approach.

Incidentally, I'm thinking this idea/technique could probably be leveraged to solve this other question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

少女情怀诗 2024-11-14 17:21:13

这个将使用空字符串

DECLARE @InputString VARCHAR(1000)
    SELECT @InputString = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,,1'

    SELECT SUBSTRING(',' + @InputString + ',', Number + 1,
    CHARINDEX(',', ',' + @InputString + ',', Number + 1) - Number -1)AS VALUE
    FROM master..spt_values
    WHERE type = 'p'
    AND Number <= LEN(',' + @InputString + ',') - 1
    AND SUBSTRING(',' + @InputString + ',', Number, 1) = ','
    GO

另请看一下此处的注释:SSQL Server 2005+ CLR 与 T-SQL 中的分割字符串以获得其他一些想法

This one will work with empty strings

DECLARE @InputString VARCHAR(1000)
    SELECT @InputString = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,,1'

    SELECT SUBSTRING(',' + @InputString + ',', Number + 1,
    CHARINDEX(',', ',' + @InputString + ',', Number + 1) - Number -1)AS VALUE
    FROM master..spt_values
    WHERE type = 'p'
    AND Number <= LEN(',' + @InputString + ',') - 1
    AND SUBSTRING(',' + @InputString + ',', Number, 1) = ','
    GO

Also take a look at the comments here: Split string in SQL Server 2005+ CLR vs. T-SQL for some other ideas

窝囊感情。 2024-11-14 17:21:13

虽然现在为时已晚,OP也有一个可接受的答案,但仍然值得一提的是阅读使用 Set base 方法在 Sql Server 中分割函数,作者展示了许多实现相同目的的方法。

Though it's too late now and also the OP has an accepted answer, but still it's worth mentioning to read the article on Split Function in Sql Server using Set base approach where the author has shown many ways of achieving the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文