1

I have a Mysql table like this

supplierranks_new

Id
supplierid
userid
rank

Now I have got a Garbage data where a user whose userid=1837 has ranked one supplier too many times so there is multiple row of the same ranking , I want to remove all those and keep one

for example

1 267 1837 23
2 267 1837 23
3 267 1837 23
4 267 1837 23
5 267 1837 23
6 268 1837 1
7 268 1837 1
8 268 1837 1
9 268 1837 1
10 268 1837 1

Now I want to change it to this

 1 267 1837 23
 6 268 1837 1

Any Idea how I can write the query

Thanks

Vikram Anand Bhushan
  • 4,836
  • 15
  • 68
  • 130

4 Answers4

2

You can use the following query:

DELETE FROM supplierranks_new
WHERE `Id` NOT IN (
  SELECT `Id`
  FROM (SELECT MIN(`Id`) AS `Id`
        FROM supplierranks_new
        GROUP BY `supplierid`, `userid`, `rank`) AS t )

This will delete any duplicate row not having the minimum Id value within the supplierid, userid, rank slice.

Note the usage of a subquery inside the NOT IN operator in order to avoid:

You can't specify target table 'supplierranks_new' for update in FROM clause

error.

Demo here

Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
Giorgos Betsos
  • 71,379
  • 9
  • 63
  • 98
0

Add Unique Index on your table,This will drop all the duplicate rows.

ALTER IGNORE TABLE supplierranks_new
ADD UNIQUE INDEX (supplierid,userid);

or this :-

ALTER TABLE supplierranks_new ADD UNIQUE supplierid ( supplierid )
Abhishek Sharma
  • 6,689
  • 1
  • 14
  • 20
  • 1
    you should have asked first (like I did). They want to delete permanently. – Funk Forty Niner Nov 23 '15 at 13:08
  • @Rahautos I want to remove those line from the table – Vikram Anand Bhushan Nov 23 '15 at 13:08
  • As per your edit, read the comments from above: *"I'd recommend that you add constraints to make it impossible for a user to rate a supplier incorrectly. Let the database enforce it. – duffymo 14 mins ago"* --- *"@duffymo actually its already there it happened I was fiddeling with a file on the live server and I am using Laravel something went wrong and on that point of time when the user ranked it saved multiple rows in the DB – Vikram 13 mins ago"* – Funk Forty Niner Nov 23 '15 at 13:25
  • I thought this latest edit would work. Maybe my settings are wrong, but MySQL doesn't seem to like this - regardless of whether the PK has been removed. – Strawberry Nov 23 '15 at 13:36
0
DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,supplierid INT NOT NULL
,userid INT NOT NULL
,rank INT NOT NULL
);

INSERT INTO my_table VALUES
(1,267,1837,23),
(2 ,267 ,1837 ,23),
(3 ,267 ,1837 ,23),
(4 ,267 ,1837 ,23),
(5 ,267 ,1837 ,23),
(6 ,268 ,1837 ,1),
(7 ,268 ,1837 ,1),
(8 ,268 ,1837 ,1),
(9 ,268 ,1837 ,1),
(10 ,268 ,1837, 1);

CREATE TABLE my_new_table 
(supplierid INT NOT NULL
,userid INT NOT NULL
,rank INT NOT NULL
,PRIMARY KEY(supplierid,userid)
) AS 
SELECT supplierid
     , userid
     , MIN(rank) rank 
  FROM my_table 
 GROUP 
    BY supplierid
     , userid;

Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

SELECT * FROM my_new_table;
+------------+--------+------+
| supplierid | userid | rank |
+------------+--------+------+
|        267 |   1837 |   23 |
|        268 |   1837 |    1 |
+------------+--------+------+
Strawberry
  • 33,750
  • 13
  • 40
  • 57
0

Although, I would go for adding UNIQUE to (supplierid, userid), which should take care of duplicate rows.

Else, instead of subqueries, I would rather go for:

DELETE sn1 
FROM supplierranks_new sn1, supplierranks_new sn2
  WHERE sn1.id > sn2.id
    AND sn1.supplierid = sn2.supplierid
    AND sn1.userid = sn2.userid
;

In the JOIN of same table, delete all the records with matching conditions and with id of first greater than id of second. This yields records with least id. If you want records with latest id, simply inverse the greater than condition:

WHERE sn1.id < sn2.id

HTH

Harsh Gupta
  • 4,348
  • 2
  • 25
  • 30