【问题标题】:T-SQL - only stuff / concatenate some columns and drop xmlT-SQL - 仅填充/连接一些列并删除 xml
【发布时间】:2021-08-30 16:24:06
【问题描述】:

我有一张这样的桌子:

ID C1 C2 seq
1 This is my re ally long sentence 1
1 This is my re stored in a 2
1 This is my re really terrible format 3

我需要一些 SQL 查询或存储过程将其拉出,使其显示为“这是我的非常长的句子,以非常糟糕的格式存储”

select 
    case 
       when seq = '1' 
          then c1 else '' 
    end + stuff((select c2 from table t2 
                 where t2. id = t1.id and t2.seq = t1.seq
                 for xml path('')), 1, 1, '') 
from 
    table t1

我已经完成了,但它正在将 XML 放入其中,我不知道为什么。任何帮助表示赞赏。

【问题讨论】:

  • 什么版本的 SQL Server?

标签: sql-server tsql stuff


【解决方案1】:

想通了。 for xml 并没有像我想的那样删除 XML,只有前导字符,我不得不将 c1 转换为 nvarchar 导致一个未命名的列并且没有 xml:耸耸肩:

【讨论】:

    【解决方案2】:

    FOR XML 将使用列名作为节点名,所以如果你有

    SELECT someCol
    FROM tbl
    FOR XML PATH('')
    

    你仍然会得到这样的 XML

    <someCol>someValue</someCol>
    

    这个连接技巧的要点是获取一个未命名的列,这样就没有节点名称,只有值。所以你只需要对值使用 any 函数或计算来删除列名

    在您的情况下,STUFF 不是必需的,因为您没有分隔符。

    不要忘记使用, TYPE).value('text()[1]','nvarchar(max)') 来防止 XML 转义/实体化。

    select 
        c1 + (
            select case when 1=1 then c2 end
            from table t2 
            where t2.id = t1.id and t2.seq >= 2
            for xml path(''), type).value('text()[1]','nvarchar(max)')
    from 
        table t1
    where seq = '1';
    

    当然,如果您使用的是 SQL Server 2017+,则可以使用 STRING_AGG

    select 
        c1 + string_agg(cast(c2 as nvarchar(max)), '')
    from 
        table t1
    group by t1.ID, t1.c1;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多