简体   繁体   中英

MySQL delete duplicates in same table

I've been slamming my head on this problem and viewed a few similar situations on stack exchange and the more I read the more confused I get! I have a table that has the following:

id | zipcode | provider | channel
---------------------------------
1  | 91773   | 342      | 0
2  | 91773   | 2261     | 177
3  | 91773   | 5590     | 0
4  | 91773   | 5590     | 0
5  | 91773   | 5590     | 135
6  | 91773   | 5590     | 0
7  | 91773   | 6010     | 0
8  | 91773   | 6010     | 0

I want to keep only one record and if the channel has anything but a 0 then we keep it. So it should return this:

id | zipcode | provider | channel
---------------------------------
1  | 91773   | 342      | 0
2  | 91773   | 2261     | 177
5  | 91773   | 5590     | 135
8  | 91773   | 6010     | 0

I tried quite a few queries, but none worked. Thanks in advance.

Edit: I've tried some of the examples given, but none seem to give back the correct info, a better example would be to use these and you can see why: insert into unicorns values

(1, 91773, 342, 0),
(2, 91773, 2261, 177),
(3, 91773, 5590, 0),
(4, 91773, 5590, 0),
(5, 91773, 5590, 135),
(6, 91773, 5590, 0),
(7, 91773, 6010, 0),
(8, 91773, 6010, 0),
(9, 91776, 5590, 135),
(10, 91776, 5590, 0),
(11, 91776, 6010, 0),
(12, 91776, 6010, 0);

Something like this should work...

DELETE unicorns 
FROM   unicorns 
WHERE  id NOT IN (SELECT id 
                  FROM   (SELECT unicorns.provider, 
                                 Max(id) AS id 
                          FROM   unicorns 
                                 LEFT JOIN (SELECT provider, 
                                                   Max(channel) AS channel 
                                            FROM   unicorns 
                                            GROUP  BY provider) p 
                                        ON p.provider = unicorns.provider 
                                           AND p.channel = unicorns.channel 
                          WHERE  p.provider IS NOT NULL 
                          GROUP  BY unicorns.provider) p2) 

See the demo

You can perform this using a self join. If you are just doing the delete:

DELETE a
FROM foo a 
  JOIN foo b on (a.zipcode = b.zipcode AND a.provider = b.provider)
WHERE 
  a.channel < b.channel;

If you want to see the data before you delete(what will be left):

SELECT * 
FROM foo
WHERE ID NOT IN (
 SELECT a.id
 FROM foo a 
   JOIN foo b on (a.zipcode = b.zipcode AND a.provider = b.provider)
 WHERE 
   a.channel < b.channel);

SQL Fiddle demo

I think you could use something like this:

delete from unicorns
where id not in (
  SELECT * FROM (
    SELECT MAX(id)
    FROM unicorns
    WHERE (provider, zipcode, channel) IN (
      SELECT provider, zipcode, max(channel) mx_channel
      FROM unicorns
      GROUP BY provider, zipcode
    )
    GROUP BY provider, zipcode) s)

Please see fiddle here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM