【问题标题】:Remove duplicate while concatenating other columns values在连接其他列值时删除重复项
【发布时间】:2019-04-25 17:37:22
【问题描述】:

我的数据表如下(表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 是重复的,而其他列不重复)

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

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

【问题讨论】:

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


    【解决方案1】:

    刚刚看到您对 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,这就是我在做替代品的原因。

    【讨论】:

    • 刚刚通过“string_agg”。很高兴知道这一点。
    【解决方案2】:

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

    尝试在该列中使用内容

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

    stuff逻辑是去掉第一个'和'

    【讨论】:

    • 出现错误:“stuff 函数需要 4 个参数”。注意:现在我正在使用 SSMS 和 SQL Server 2017。此外,您能否提供更多详细信息,关于此查询如何工作/查询流程?
    • 我相信, len 将采用一个参数,而在您的查询中有 2 个参数。最后一个参数应该来自 len 并且应该用于东西。不错,顺便看看 XML 路径是如何工作的。
    • 对不起。我只是在答案中输入了这个并没有检查它。我会更新内容
    • 我错过了 len(' and ') 中的括号
    【解决方案3】:
    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
    

    【讨论】:

      【解决方案4】:

      你可以试试这个:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-11
        • 2019-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多