串联其他列值时删除重复项

时间:2019-04-25 17:37:22

标签: sql-server sql-server-2012 sql-server-2008-r2 sql-server-2016

我的数据表如下图(表1)

            Table1
            ------------------------------------------
            ID  | IPaddress     | Port  | Value
            ----|---------------|-------|-------------      
            1   | xx.yy.14.15   | 332   | This is good
            ------------------------------------------      
            2   | xx.yy.14.15   | 332   | I can work
            ------------------------------------------
            3   | xx.yy.12.12   | 400   | Looks ok
            ------------------------------------------
            4   | xx.yy.12.12   | 400   | can I work
            ------------------------------------------
            5   | xx.yy.12.12   | 400   | Yes, please
            -------------------------------------------
            6   | xx.yy.14.16   | 401   | How is this
            -------------------------------------------
            7   | xx.yy.14.16   | 401   | Looks ok
            -------------------------------------------
            8   | xx.yy.14.16   | 401   | can I work
            -------------------------------------------
            9   | xx.yy.14.16   | 401   | Yes, please
            -------------------------------------------

所需结果表:

            ID  | IPaddress     | Port  | Value
            ----|---------------|-------|-----------------------------------------------------------        
            1   | xx.yy.14.15   | 332   | This is good and I can work
            --------------------------------------------------------------------------------------      
            2   | xx.yy.12.12   | 400   | Looks ok and can I work and Yes, please
            ---------------------------------------------------------------------------------------
            3   | xx.yy.14.16   | 401   | How is this and Looks ok and can I work and Yes, please
            ---------------------------------------------------------------------------------------

这是我尝试过的:

            DECLARE @VAR1 VARCHAR(50)
            DECLARE @VAR2 VARCHAR(50)

            SELECT @VAR1 = T1.VALUE,@VAR2=T2.VALUE
            FROM TABLE1 AS T1 INNER JOIN TABLE1 AS T2 ON T1.ID =T2.ID
            WHERE T1.IPADDRESS =T2.IPADDRESS

            SELECT IPADDRSS,PORT,@VAR1 + ' AND ' +@VAR2 FROM
              SELECT T1.*,
              ROW_NUMBER() OVER (PARTITION BY T1.IPADDRESS,T1.PORT ORDER BY VALUE) AS NM
              FROM TABLE1 AS T1
              )TBL
            WHERE NM = 1

但是,从上面的查询中,如果只有2个重复的行,我就能实现所需的输出 (注意:这里我考虑将IPADDRESS和PORT视为重复项,而其他列则不重复)

但是,当3行,4行或5行中有相同的IPADDRESS和PORT时,如何获得我想要的结果?请注意,具有相同IPADDRESS和PORT的行数是动态的,有时可能会超过10。 那么,如何在获得预期结果的同时处理这种动态情况呢?

希望我正确地解释了这一点。请帮忙。谢谢

4 个答案:

答案 0 :(得分:2)

仅在SQL 2017中看到了您的评论。Shoulda预先说过,我一直在研究一种使我感到痛苦的老式聚合技术。 SQL 2017为我们提供了过期已久的string_agg函数,这使它变得非常简单:

SELECT
   row_number() over (order by IPaddress, Port) ID
  ,IPaddress
  ,Port
  ,string_agg(Value, ' and ')
 from Table1
 group by 
   IPaddress
  ,Port

如果订购很关键,您可能需要戳一下。

@KeithL的版本也可以使用,但需要进行一些调试...我认为您已经解决了。我,我只是不太喜欢XML,这就是为什么我正在开发替代产品。

答案 1 :(得分:1)

这是创建定界列表(通常是逗号,但在您的情况下为'和'定界)的答案

尝试在该列中使用内容

select rownumber() over (order by IPAddress,Port),IPAddress,Port
    ,stuff((select ' and ' + value
            from table t2
            where t1.IPaddress=t2.ipaddress and t1.port=t2.port
            order by ID
            for XML path(''), type
            ).value('.','nvarchar(max)')
            ,1,len(' and '),'') as verbage
from table t1
group by IPAddress,Port

工作方式:

外部查询基本上可以在IPAddress,Port上为您提供分组的结果

相关子查询提供与IPAddress,Port关联的每一行的定界列表

填充逻辑是删除第一个'和'

答案 2 :(得分:0)

您可以尝试以下方法:

select t.* from (
select ROW_NUMBER() over (partition by port order by port) rn,id,port,value=stuff ( 
                         ( select ' ' + value from @t t
                         where t.port=t1.port
                                    for xml path ('')),1,1,''

                         ) from @t t1
                         group by id,port
) t
where rn=1

答案 3 :(得分:0)

SELECT
    t1.IpAddress,t1.port,

    value = STUFF((
        SELECT ' and ' + t2.value
        FROM Table1 t2
        WHERE t1.port = t2.port
        FOR XML PATH('')
    ),2, 3, '')
FROM Table1 t1
GROUP BY t1.port,t1.IpAddress

enter image description here