将 CSV 拆分为多行

问题描述 投票:0回答:4

我正在使用这个 SQL 团队线程(第二篇文章)中的 split 函数和以下查询。

--This query converts the interests field from text to varchar
select
    cp.id
    ,cast(cp.interests as varchar(100)) as interests
into #client_profile_temp
from
    client_profile cp

--This query is supposed to split the csv ("Golf","food") into multiple rows            
select
    cpt.id
    ,split.data
from
    #client_profile_temp cpt
    cross apply dbo.split(
    cpt.interests, ',') as split  <--Error is on this line

但是我得到了

“.”附近的语法不正确 我在上面标记的地方有错误。

最后我想要

ID              INTERESTS
000CT00002UA    "Golf","food"

成为

ID              INTERESTS
000CT00002UA    "Golf"
000CT00002UA    "food"

我正在使用 SQL Server 2008,我的答案基于 这个 StackOverflow 问题

sql sql-server
4个回答
10
投票

桌子

x-----------------x--------------------x
|       ID        |     INTERESTS      |
x-----------------x--------------------x
|  000CT00002UA   |    Golf,food       |
|  000CT12303CB   |    Cricket,Bat     |
x------x----------x--------------------x


方法1:使用

XML
格式

SELECT ID,Split.a.value('.', 'VARCHAR(100)') 'INTERESTS' 
FROM  
(
     -- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
     SELECT ID, CAST ('<M>' + REPLACE(INTERESTS, ',', '</M><M>') + '</M>' AS XML) AS Data 
     FROM TEMP     
) AS A 
CROSS APPLY Data.nodes ('/M') AS Split(a)

方法2:使用函数

dbo.Split

SELECT a.ID, b.items
FROM #TEMP a
CROSS APPLY dbo.Split(a.INTERESTS, ',') b

还有

dbo.Split
功能在这里。

CREATE FUNCTION [dbo].[Split](@String varchar(8000), @Delimiter char(1))     
returns @temptable TABLE (items varchar(8000))     
as     
begin     
declare @idx int     
declare @slice varchar(8000)     

select @idx = 1     
    if len(@String)<1 or @String is null  return     

while @idx!= 0     
begin     
    set @idx = charindex(@Delimiter,@String)     
    if @idx!=0     
        set @slice = left(@String,@idx - 1)     
    else     
        set @slice = @String     

    if(len(@slice)>0)
        insert into @temptable(Items) values(@slice)     

    set @String = right(@String,len(@String) - @idx)     
    if len(@String) = 0 break     
end 
return     
end

最终结果

enter image description here


8
投票
from
    #client_profile_temp cpt
    cross apply dbo.split(
    #client_profile_temp.interests, ',') as split  <--Error is on this line

我认为在给 #client_profile_temp 一个别名后显式命名它是一个问题,尝试制作最后一行:

    cpt.interests, ',') as split  <--Error is on this line

编辑你说

我做了这个改变,但它没有改变任何东西

尝试粘贴下面的代码(到新的 SSMS 窗口中)

create table #client_profile_temp
(id int,
interests varchar(500))

insert into  #client_profile_temp
values
(5, 'Vodka,Potassium,Trigo'),
(6, 'Mazda,Boeing,Alcoa')

select
   cpt.id
  ,split.data
from
    #client_profile_temp cpt
    cross apply dbo.split(cpt.interests, ',') as split 

看看它是否按您的预期工作;我正在使用 sql server 2008,这对我来说可以得到我认为你想要的结果。

当您说“我进行了更改”时,您是否有可能只是更改了存储过程但尚未运行它,或者更改了创建存储过程的脚本但未运行该脚本,类似的情况? 正如我所说,它似乎对我有用。


3
投票

由于这是旧的,因此以下内容似乎在 SQL Azure 中有效(截至 3/2022) 最大的变化是 split.value 而不是 .data 或 .items,如上所示;函数后面没有,最后 string_split 是方法。

select Id, split.value
from #reportTmp03 rpt
cross apply string_split(SelectedProductIds, ',') split

0
投票

试试这个:

--This query is supposed to split the csv ("Golf","food") into multiple rows             
select 
    cpt.id 
    ,split.data 
from 
    #client_profile_temp cpt 
    cross apply dbo.split(cpt.interests, ',') as split  <--Error is on this line 

定义表后必须立即使用表别名而不是表名。

© www.soinside.com 2019 - 2024. All rights reserved.