MySQL: Найти дубликаты записей, но ИСКЛЮЧИТЬ первую из списка - PullRequest
1 голос
/ 25 марта 2020

У меня есть таблица ниже:

MariaDB [groupdb]> select * from album;    
+----+---------+---------+
| id | artist  | user_id |
+----+---------+---------+
|  1 | ArtistX |   45677 |
|  2 | ArtistY |  378798 |
|  3 | ArtistX |   45677 |
|  4 | ArtistZ |  123456 |
|  5 | ArtistY |  888888 |
|  6 | ArtistX |    2312 |
|  7 | ArtistY |  378798 |
|  8 | ArtistY |  888888 |
|  9 | ArtistY |  888888 |
+----+---------+---------+
9 rows in set (0.000 sec)

Я попытался найти дубликаты записей с запросом ниже:

MariaDB [groupdb]> select * from album where artist IN (select artist from album group by artist having count(artist)>1) and user_id IN (select user_id from album group by user_id having count(user_id)>1);
+----+---------+---------+
| id | artist  | user_id |
+----+---------+---------+
|  1 | ArtistX |   45677 |
|  2 | ArtistY |  378798 |
|  3 | ArtistX |   45677 |
|  5 | ArtistY |  888888 |
|  7 | ArtistY |  378798 |
|  8 | ArtistY |  888888 |
|  9 | ArtistY |  888888 |
+----+---------+---------+
7 rows in set (0.001 sec)    

Это все хорошо и хорошо. Хотя я хочу, чтобы в моем наборе результатов был список дубликатов, кроме первого. то есть аналогично приведенному ниже.
ОЖИДАЕМЫЙ ВЫХОД

+----+---------+---------+
| id | artist  | user_id |
+----+---------+---------+
|  3 | ArtistX |   45677 |
|  7 | ArtistY |  378798 |
|  8 | ArtistY |  888888 |
|  9 | ArtistY |  888888 |
+----+---------+---------+

Как вы можете видеть выше, это список дубликатов, исключая первый.

ПРИМЕЧАНИЕ: Чтобы запись была дубликатом, оба Artist и user_id должны быть одинаковыми.
Моя задача придумать запрос, ведущий к этому результату выше.

Ответы [ 4 ]

1 голос
/ 25 марта 2020

Вы хотите выбрать все строки, для которых существует брат с меньшим идентификатором. Самый простой способ express это на мой взгляд:

select * 
from album a
where exists
(
  select * 
  from album a2
  where a2.artist = a.artist
  and a2.user_id = a.user_id
  and a2.id < a.id
)
order by id;
1 голос
/ 25 марта 2020

Вы можете использовать row_number(), чтобы получить по одной строке на исполнителя / user_id:

select a.*
from (select a.*,
             row_number() over (partition by artist, user_id order by id) as seqnum
      from album a
     ) a
where seqnum > 1;

В старых версиях вы можете использовать:

select a.*
from album a
where a.id > (select min(a2.id)
              from album a2
              where a2.artist = a.artist and a2.user_id = a.user_id
             );
1 голос
/ 25 марта 2020

MariaDB 10.3 и выше поддерживают функцию except, поэтому вы можете просто сделать

select id, artist, user_id
from t
except 
select min(id), artist, user_id
from t
group by artist, user_id;

Если это не вариант, вы можете использовать not in

select id, artist, user_id
from t
where (id, artist, user_id) not in (select min(id), artist, user_id
                                    from t
                                    group by artist, user_id);
1 голос
/ 25 марта 2020

Это легко сделать в последних версиях MariaDB, которые поддерживают ROW_NUMBER:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY artist, user_id ORDER BY id) rn
    FROM album
)

SELECT id, artist, user_id
FROM cte
WHERE rn > 1;

Вот как будет выглядеть промежуточный CTE, использованный в приведенном выше запросе:

+----+---------+---------+----+
| id | artist  | user_id | rn |
+----+---------+---------+----+
|  1 | ArtistX |   45677 | 1  |
|  2 | ArtistY |  378798 | 1  |
|  3 | ArtistX |   45677 | 2  |
|  4 | ArtistZ |  123456 | 1  |
|  5 | ArtistY |  888888 | 1  |
|  6 | ArtistX |    2312 | 1  |
|  7 | ArtistY |  378798 | 2  |
|  8 | ArtistY |  888888 | 2  |
|  9 | ArtistY |  888888 | 3  |
+----+---------+---------+----+

Обратите внимание, что парам исполнитель / пользователь_идентификатор, у которых нет дубликатов, будет назначен только номер строки 1, и поэтому они никогда не будут сохраняться в выходных данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...