【问题标题】:Show all rows that have certain columns duplicated显示具有重复某些列的所有行
【发布时间】:2012-04-25 21:30:52
【问题描述】:

假设我有以下 sql 表

    objid  firstname lastname active
     1       test      test     0
     2       test      test     1
     3       test1     test1    1
     4       test2     test2    0
     5       test2     test2    0
     6       test3     test3    1

现在,我感兴趣的结果如下:

     objid  firstname lastname active
     1       test      test     0
     2       test      test     1
     4       test2     test2    0
     5       test2     test2    0

我怎样才能做到这一点? 我尝试了以下查询,

select firstname,lastname from table
group by firstname,lastname
having count(*) > 1

但是这个查询给出的结果类似于

    firstname  lastname
     test        test
     test2       test2

【问题讨论】:

    标签: sql sql-server-2008


    【解决方案1】:

    您已找到重复记录,但您有兴趣获取附加到它们的所有信息。您需要 join 将您的副本发送到您的主表以获取该信息。

    select *
      from my_table a
      join ( select firstname, lastname 
               from my_table 
              group by firstname, lastname 
             having count(*) > 1 ) b
        on a.firstname = b.firstname
       and a.lastname = b.lastname
    

    这与inner join 相同,意味着对于您的子查询中的每条记录,您可以从主表中找到具有相同 firstseen 和 lastseen 组合的所有记录。

    您也可以使用though you should test the difference

    select *
      from my_table a
     where ( firstname, lastname ) in   
           ( select firstname, lastname 
               from my_table 
              group by firstname, lastname 
             having count(*) > 1 )
    

    延伸阅读:

    【讨论】:

    • 这个语法在 sql server 中有效吗? where ( firstname, lastname ) in ( select firstname, lastname from my_table group by firstname, lastname have count(*) > 1 )
    • 你运行过@nee21 吗?你遇到了什么问题?
    • 是的,我收到此错误:消息 4145,级别 15,状态 1,第 161 行 在预期条件的上下文中指定的非布尔类型表达式,靠近“,”。我不确定是否缺少任何东西。
    • 嗨@Ben,你有机会检查一下吗?
    • 我认为它不适用于 sql server @Ben。 op将sql server 2008作为标签
    【解决方案2】:
    SELECT DISTINCT t1.*
    FROM myTable AS t1
    INNER JOIN myTable AS t2
      ON t1.firstname = t2.firstname
      AND t1.lastname = t2.lastname
      AND t1.objid <> t2.objid
    

    这将根据firstnamelastname 输出具有重复项的每一行。

    【讨论】:

    • 你可能指的是objid而不是id
    • 另外,如果你不区分结果,你会得到重复。
    【解决方案3】:

    这里有一个更清晰的方式来做 Ben 的第一个答案:

    WITH duplicates AS (
       select    firstname, lastname
       from      my_table
       group by  firstname, lastname
       having    count(*) > 1
    )
    SELECT    a.*
    FROM      my_table   a
    JOIN      duplicates b ON (a.firstname = b.firstname and a.lastname = b.lastname)
    

    【讨论】:

    • 一个简单的连接(如我的回答)不会比连接到一个分组的临时表更快吗?
    • @Shedal:它们应该是一样的。子查询是一个临时表。以上是简化读取SQL的一种方式。通过预先声明/定义子查询,您可以专注于后续 SQL 的核心
    • @Shedal,这取决于。例如,如果firstname, lastname 上有一个索引(尽管我为你 +1,因为这只是一种不同的做事方式)。
    • @Ben 无论如何,firstname, lastname 上应该有一个索引,以便两个查询都能快速运行。
    • @Shedal,子查询将只使用索引,但连接必须使用两个索引(除非它在obj_id, fn, ln 上建立索引)或进入表。另外,没有必要做一个独特的。如果不测试和了解色谱柱的选择性,就无法判断哪个会更快。
    【解决方案4】:
    SELECT user_name,email_ID 
    FROM User_Master WHERE 
    email_ID 
    in (SELECT email_ID 
    FROM User_Master GROUP BY 
    email_ID HAVING COUNT(*)>1) 
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
    【解决方案5】:

    不错的选项从表中获取所有重复值

     select * from Employee where Name in (select Name from Employee group by Name having COUNT(*)>1)
    

    【讨论】:

      【解决方案6】:

      这是最简单的方法:

      SELECT * FROM yourtable a WHERE EXISTS (SELECT * FROM yourtable b WHERE a.firstname = b.firstname AND a.secondname = b.secondname AND a.objid <> b.objid)
      

      【讨论】:

        【解决方案7】:

        如果要打印表中所有重复的 ID:

        select * from table where id in (select id from table group By id having count(id)>1)
        

        【讨论】:

          【解决方案8】:

          我很惊讶使用 Window function 没有答案。我刚刚遇到了这个用例,这对我有帮助。

          select t.objid, t.firstname, t.lastname, t.active
          from
          (
          select t.*, count(*) over (partition by firstname, lastname) as cnt
          from my_table t
          ) t
          where t.cnt > 1;
          

          小提琴 - https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=c0cc3b679df63c4d7d632cbb83a9ef13


          格式如下

          select
              tbl.relevantColumns
          from
          (
              select t.*, count(*) over (partition by key_columns) as cnt
              from desiredTable t
          ) as tbl
          where tbl.cnt > 1;
          

          此格式从表中选择您需要的任何列(有时是所有列),其中count &gt; 1 用于标识重复行。 key_columns 可以是任意数量的列。

          【讨论】:

            【解决方案9】:

            这个答案可能不是很好,但我认为它很容易理解。

            SELECT * FROM table1 WHERE (firstname, lastname) IN ( SELECT firstname, lastname FROM table1 GROUP BY firstname, lastname having count() > 1);
            

            【讨论】:

              【解决方案10】:

              此查询返回重复项

              SELECT * FROM (
                SELECT  a.* 
                  FROM table a 
                  WHERE (`firstname`,`lastname`) IN (
                      SELECT `firstname`,`lastname` FROM table 
                      GROUP BY `firstname`,`lastname` HAVING COUNT(*)>1       
                      )  
                  )z WHERE z.`objid` NOT IN (
                      SELECT MIN(`objid`) FROM table 
                      GROUP BY `firstname`,`lastname` HAVING COUNT(*)>1
                      )                                         
              

              【讨论】:

                【解决方案11】:

                请尝试

                WITH cteTemp AS (
                  SELECT EmployeeID, JoinDT,
                     row_number() OVER(PARTITION BY EmployeeID, JoinDT ORDER BY EmployeeID) AS [RowFound]
                  FROM dbo.Employee 
                )
                SELECT * FROM cteTemp WHERE [RowFound] > 1 ORDER BY JoinDT
                

                【讨论】:

                  猜你喜欢
                  • 2017-02-26
                  • 2019-01-06
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-11-21
                  • 1970-01-01
                  • 2019-10-22
                  • 2014-07-31
                  相关资源
                  最近更新 更多