简体   繁体   中英

want to remove duplicates in SQL

I am creating an app with rails.
I'm stuck with how to write SQL statements, so please teach me.

want to

From this, narrow down by "competition_id" and extract only one item with the smallest "id".

For example,

+----------------+----+---------------------------+----------------+-------+-----+
| competition_id | id | image                     | name           | count | rnk |
+----------------+----+---------------------------+----------------+-------+-----+
|              1 |  4 | monster4.jpeg             | monster4       |     7 |   1 |
|              2 |  6 | monster2.jpeg             | monster2       |     1 |   1 |
|              3 |  9 | monster1.jpeg             | monster1       |     1 |   1 |
|              5 | 22 | drink_sample.jpeg         | drink6         |     2 |   1 |
|              6 | 33 | sumo_wrestler_sample.jpeg | sumo_wrestler7 |     2 |   1 |
|              7 | 40 | movie_sample.jpeg         | movie4         |     2 |   1 |
|              8 | 50 | food_sample.jpeg          | food4          |     2 |   1 |
|              9 | 61 | color_sample.jpeg         | color5         |     3 |   1 |
|             10 | 72 | book_sample.jpeg          | book6          |     2 |   1 |
|             11 | 82 | book_sample.jpeg          | book6          |     3 |   1 |
+----------------+----+---------------------------+----------------+-------+-----+

Current status

+----------------+----+---------------------------+----------------+-------+-----+
| competition_id | id | image                     | name           | count | rnk |
+----------------+----+---------------------------+----------------+-------+-----+
|              1 |  4 | monster4.jpeg             | monster4       |     7 |   1 |
|              2 |  6 | monster2.jpeg             | monster2       |     1 |   1 |
|              3 |  9 | monster1.jpeg             | monster1       |     1 |   1 |
|              5 | 22 | drink_sample.jpeg         | drink6         |     2 |   1 |
|              6 | 33 | sumo_wrestler_sample.jpeg | sumo_wrestler7 |     2 |   1 |
|              6 | 34 | sumo_wrestler_sample.jpeg | sumo_wrestler8 |     2 |   1 |
|              6 | 35 | sumo_wrestler_sample.jpeg | sumo_wrestler9 |     2 |   1 |
|              7 | 40 | movie_sample.jpeg         | movie4         |     2 |   1 |
|              7 | 43 | movie_sample.jpeg         | movie7         |     2 |   1 |
|              7 | 45 | movie_sample.jpeg         | movie9         |     2 |   1 |
|              8 | 50 | food_sample.jpeg          | food4          |     2 |   1 |
|              8 | 56 | food_sample.jpeg          | food10         |     2 |   1 |
|              9 | 61 | color_sample.jpeg         | color5         |     3 |   1 |
|             10 | 72 | book_sample.jpeg          | book6          |     2 |   1 |
|             11 | 82 | book_sample.jpeg          | book6          |     3 |   1 |
+----------------+----+---------------------------+----------------+-------+-----+

The code that extracted this

SELECT * FROM (SELECT *,RANK() OVER (PARTITION BY competition_id ORDER BY COUNT DESC) rnk FROM (SELECT items.competition_id,items.id,items.image,items.name,count(*) AS count FROM chosenitems INNER JOIN items ON chosenitems.item_id = items.id GROUP BY items.competition_id,items.id) AS t) AS tt WHERE rnk = 1;

Table structure

  • chosenitems table
id session_id item_id
1 1 2
2 1 3
2 1 2
2 1 2
2 1 5
3 1 7
4 1 4
5 1 5
  • items table
id name image competition_id
1 a image1 1
2 b image2 1
2 c image2 1
2 d image2 1
2 e image5 2
3 f image9 2
4 g image4 2
5 h image5 2

I tried

SELECT * FROM (SELECT *,RANK() OVER (PARTITION BY competition_id ORDER BY COUNT DESC) rnk FROM (SELECT items.competition_id,items.id,items.image,items.name,count(*) AS count FROM chosenitems INNER JOIN items ON chosenitems.item_id = items.id GROUP BY items.competition_id,items.id) AS t) AS tt WHERE id in (SELECT MIN(id) FROM chosenitems GROUP BY competition_id);

Failure

+----------------+----+---------------+----------+-------+-----+
| competition_id | id | image         | name     | count | rnk |
+----------------+----+---------------+----------+-------+-----+
|              1 |  1 | monster1.jpeg | monster1 |     4 |   2 |
+----------------+----+---------------+----------+-------+-----+

I want to extract the one with the smallest id from each "competition_id" where "rnk" is 1.

environment

macOS BigSur
ruby 2.7.0
Rails 6.1.1
mysql Ver 8.0.23

This should give you the wanted result, you must check if MIN is the right choice for every value

SELECT 
    competition_id
    ,MIN(id) as id
    ,MIN(mage) as image
    ,MIN(ame) as name
    ,MIN(count) as count
   ,MIN(rnk) as rnk
FROM 
    (SELECT 
        *
        ,RANK() OVER (PARTITION BY competition_id ORDER BY COUNT DESC) rnk 
    FROM (SELECT 
            items.competition_id
            ,items.id
            ,items.image
            ,items.name
            ,count(*) AS count 
        FROM 
            chosenitems INNER JOIN items ON chosenitems.item_id = items.id 
            GROUP BY items.competition_id,items.id) AS t) AS tt 
WHERE rnk = 1
GROUP BY competition_id;

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