【问题标题】:TSQL, change value on a comma delimited columnTSQL,更改逗号分隔列的值
【发布时间】:2017-03-06 02:43:05
【问题描述】:

我有一个名为 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 = ''

【问题讨论】:

  • 听起来你需要规范化你的数据结构。
  • 这不是我的数据库,我得到了它并被告知将这些数据导出到 Excel 电子表格中。

标签: sql-server tsql


【解决方案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(length) 以避免截断。我还假设 ID1 和 ID2 都形成了一个复合键(看起来就是这样)。根据关系的需要调整联接。

【讨论】:

  • 嗨,感谢您的回复,在我看到这篇文章之前,我想出了一个不太优雅的方法,它在上面的编辑中。
【解决方案2】:

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

试试这个,

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

【讨论】:

    【解决方案3】:

    你可以通过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
    

    和用例语句删除空值

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

    【讨论】:

      猜你喜欢
      • 2014-07-20
      • 2015-09-05
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 1970-01-01
      • 2018-06-01
      相关资源
      最近更新 更多