连接其他列值时删除重复项

Remove duplicate while concatenating other columns values

我的数据 table 如下所示(表 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
            -------------------------------------------

想要的结果table:

            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。 那么,如何在获得理想结果的同时处理这种动态情况?

希望我解释正确。请帮忙。谢谢

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

尝试在该列中使用内容

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 关联的每一行的分隔列表

内容逻辑是删除第一个'和'

刚刚看到你的评论回复:SQL 2017。应该在前面说过,我一直在研究一种让我伤心的老式聚合技术。 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,这就是为什么我正在研究替代品。

你可以试试这个:

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
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