TSQL,更改逗号分隔列的值

时间:2017-03-06 02:43:05

标签: sql-server tsql

我有一个名为empl_type_multi的列,它只是一个以逗号分隔的列,每个值都是指向另一个名为自定义标题的表的链接。

例如,我可能将以下内容作为empl_type_multi中的值:

123, RHN, 458

然后在custom_captions表中,这些将是单独的值:

123 = Dog
RHN = Cat
458 = Rabbit

所有这些字段都是NTEXT。

我要做的是转换empl_type_multi列并将其转换为custom_captions表中的相应名称,因此在上面的示例中:

123, RHN, 458

会变成

Dog, Cat, Rabbit

对此的任何帮助都将非常感激。

-----编辑----------------------------------------- -------------------------

好的,所以我设法将值转换为相应的标题并将其全部放入临时表中,以下是表格上CTE查询的输出:

ID1     ID2     fName   lName   Caption_name        Row_Number
10007   22841   fname1  lname1  DENTAL ASSISTANT    1
10007   22841   fname1  lname1                      2
10007   22841   fname1  lname1                      3
10008   23079   fname2  lname2  OPS WARD            1
10008   23079   fname2  lname2  DENTAL              2
10008   23079   fname2  lname2                      3

如何更新此项,以便将标题名称下的任何内容添加到以逗号分隔的Row_Number 1的标题名称中?

如果我能做到这一点,我需要做的就是删除Row_Number!= 1的所有记录。

------编辑---------------------------------------- ----------

第一次编辑的解决方案是:

WITH CTE AS 
(
    SELECT
        p.ID1
        , p.ID2
        , p.fname
        , p.lname
        , p.caption_name--
        , ROW_NUMBER() OVER (PARTITION BY p.id1ORDER BY caption_name DESC) AS RN
    FROM tmp_cs p
)
UPDATE tblPerson SET empType = empType + ', ' + c.Data
FROM CTE c WHERE [DB1].dbo.tblPerson.personID = c.personID AND RN = 2

然后我只增加了RN = 2,直到我受到0行影响。

这是在我跑完之后:

DELETE FROM CTE WHERE RN != 1 AND Caption_name = ''

3 个答案:

答案 0 :(得分:1)

select ID1, ID2, fname, lname, left(captions, len(captions) - 1) as captions
from (
    select distinct ID1, ID2, cast(fname as nvarchar) as fname, cast(lname as nvarchar) as lname, (
        select cast(t1.caption_name as nvarchar) + ',' 
        from #temp as t1
        where t1.ID1 = t2.ID1
        and t1.ID2 = t2.ID2
        and cast(caption_name as nvarchar) != ''
        order by t1.[row_number]
        for xml path ('')) captions
    from #temp as t2
) yay_concatenated_rows

这会给你你想要的。你会看到从ntext转换为varchar。这对于比较是必要的,因为许多逻辑操作不能在ntext上执行。它可以隐含地退回到其他方面,所以不用担心。注意,在施法时我没有指定长度;这将默认为30,因此根据需要调整为varchar(长度)以避免截断。我还假设ID1和ID2都形成一个复合键(看起来就是这样)。根据需要调整关联。

答案 1 :(得分:1)

你刚刚分享了你的问题,而不是确切的问题。

试试这个,

DECLARE @T TABLE(ID1 VARCHAR(50),ID2 VARCHAR(50),fName VARCHAR(50),LName VARCHAR(50),Caption_name VARCHAR(50),Row_Number INT)
INSERT INTO @T VALUES
(10007,22841,'fname1','lname1','DENTAL ASSISTANT',    1)
,(10007,22841,'fname1','lname1',   NULL,                 2)
,(10007,22841,'fname1','lname1',   NULL,                 3)
,(10008,23079,'fname2','lname2','OPS WARD',            1)
,(10008,23079,'fname2','lname2','DENTAL',              2)
,(10008,23079,'fname2','lname2',  NULL,                  3)

SELECT * 
,STUFF((SELECT ','+Caption_name
FROM @T T1 WHERE T.ID1=T1.ID1 FOR XML PATH('')
),1,1,'')
FROM @T T

答案 2 :(得分:1)

您可以通过循环遍历while循环

轻松构造caption_name字符串
declare @i int = 2,@Caption_name varchar(100)= (select series from 
#temp where Row_Number= 1)
while @i <= (select count(*) from #temp)
begin
select @Caption_name = @Caption_name + Caption_name from #temp where Row_Number = @i)
set @i = @i+1
end
update #temp set Caption_name = @Caption_name where Row_Number = 1

并使用case语句删除空值

(select case when isnull(Caption_name ,'') = '' then
'' else ',' + Caption_name end