Mysql query to find all rows that have the same values as another row

前端 未结 4 670
后悔当初
后悔当初 2020-12-11 06:03

My database contains rows that generally look like:

PersonItem
__________
id
personId
itemId

╔════╦══════════╦════════╗
║ ID ║ PERSONID ║ ITEMID ║
╠════╬═══         


        
相关标签:
4条回答
  • 2020-12-11 06:30

    You can do joins to get around with duplicate records.

    SELECT  a.*
    FROM    TableName a
            INNER JOIN
            (
                SELECT  PersonID, ItemID, COUNT(*) totalCount
                FROM    TableName
                GROUP   BY PersonID, ItemID
                HAVING  COUNT(*) > 1
            ) b ON  a.PersonID = b.PersonID AND
                    a.ItemID = b.ItemID
    
    • SQLFiddle Demo

    OUTPUT

    ╔════╦══════════╦════════╗
    ║ ID ║ PERSONID ║ ITEMID ║
    ╠════╬══════════╬════════╣
    ║  1 ║      123 ║    456 ║
    ║  2 ║      123 ║    456 ║
    ║  5 ║      123 ║    456 ║
    ║  4 ║      444 ║    456 ║
    ║  7 ║      444 ║    456 ║
    ╚════╩══════════╩════════╝
    
    0 讨论(0)
  • 2020-12-11 06:38

    Something like this should do the trick:

    SELECT P1.*
    FROM PersonItem P1
    INNER JOIN PersonItem P2 ON P2.ID <> P1.ID
    AND P2.PersonId = P1.PersonId
    AND P2.ItemId =   P1.ItemId
    
    0 讨论(0)
  • 2020-12-11 06:38

    You need to find examples where the pair of personid/itemid appear more than once. In MySQL you can do this with a where clause and subquery:

    select t.*
    from t
    where exists (select 1
                  from t t2
                  group by personid, itemid
                  having count(*) > 1 and
                         t2.personid = t.personid and t2.itemid = t.itemid
                 )
    

    The above is standard SQL. MySQL also supports the multi-column in statement. So this can be written as:

    select t.*
    from t
    where (t.personid, t.itemid) in (select personid, itemid
                                     from t
                                     group by personid, itemid
                                     having count(*) > 1
                                    )
    

    And alternative that I like, based on Eugene's answer but more efficient, is:

    SELECT t.personid, t.ItemId, GROUP_CONCAT(t.ID)
    FROM t
    GROUP BY t.personid, t.ItemId
    HAVING COUNT(*) > 1;
    

    It does away with any joins, if you don't mind getting the ids as a list rather than as separate rows.

    0 讨论(0)
  • 2020-12-11 06:44
    SELECT GROUP_CONCAT(p1.ID), p1.personid, p1.ItemId
    FROM PersonItem AS p1
    INNER JOIN PersonItem AS p2  ON 
        p1.ID<>p2.ID
        AND p1.personid=p2.personid
        AND p1.ItemId=p2.ItemId
    GROUP BY p1.personid, p1.ItemId
    
    0 讨论(0)
提交回复
热议问题