Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak wybrać i/lub usunąć wszystkie poza jednym wierszem każdego zestawu duplikatów w tabeli?

Oto jedno rozwiązanie. Przetestowałem to na MySQL 5.5.8.

SELECT MAX(COALESCE(c2.id, c1.id)) AS id,
 c1.driver_id, c1.car_id,
 c2.notes AS notes
FROM cars_drivers AS c1
LEFT OUTER JOIN cars_drivers AS c2
 ON (c1.driver_id,c1.car_id) = (c2.driver_id,c2.car_id) AND c2.notes IS NOT NULL
GROUP BY c1.driver_id, c1.car_id, c2.notes;

Dołączam c2.notes jako klucz GROUP BY, ponieważ możesz mieć więcej niż jeden wiersz z notatkami innymi niż null na wartości driver_id, car_id.

Wynik na podstawie przykładowych danych:

+------+-----------+--------+-------+
| id   | driver_id | car_id | notes |
+------+-----------+--------+-------+
|    2 |         1 |      1 | NULL  |
|    4 |         2 |      1 | NULL  |
|    8 |         3 |      2 | hi    |
|    9 |         5 |      3 | NULL  |
+------+-----------+--------+-------+

Odnośnie usuwania. W przykładowych danych zawsze jest to najwyższa wartość identyfikatora na identyfikator kierowcy i identyfikator samochodu, którą chcesz zachować. Jeśli możesz na tym polegać, możesz wykonać usuwanie wielu tabel, które usuwa wszystkie wiersze, dla których istnieje wiersz o wyższym identyfikatorze i tym samym identyfikatorze kierowcy i identyfikatorze samochodu:

DELETE c1 FROM cars_drivers AS c1 INNER JOIN cars_drivers AS c2
 ON (c1.driver_id,c1.car_id) = (c2.driver_id,c2.car_id) AND c1.id < c2.id;

To naturalnie pomija wszystkie przypadki, w których istnieje tylko jeden wiersz z daną parą wartości driver_id i car_id, ponieważ warunki sprzężenia wewnętrznego wymagają dwóch wierszy z różnymi wartościami identyfikatora.

Ale jeśli nie możesz polegać na najnowszym identyfikatorze na grupę, który chcesz zachować, rozwiązanie jest bardziej złożone. Prawdopodobnie jest to bardziej skomplikowane niż to, które warto rozwiązać w jednym zdaniu, więc zrób to w dwóch zdaniach.

To też przetestowałem, po dodaniu kilku kolejnych wierszy do testowania:

INSERT INTO cars_drivers VALUES (10,2,3,NULL), (11,2,3,'bye');

+----+--------+-----------+-------+
| id | car_id | driver_id | notes |
+----+--------+-----------+-------+
|  1 |      1 |         1 | NULL  |
|  2 |      1 |         1 | NULL  |
|  3 |      1 |         2 | NULL  |
|  4 |      1 |         2 | NULL  |
|  5 |      2 |         3 | NULL  |
|  6 |      2 |         3 | NULL  |
|  7 |      2 |         3 | NULL  |
|  8 |      2 |         3 | hi    |
|  9 |      3 |         5 | NULL  |
| 10 |      2 |         3 | NULL  |
| 11 |      2 |         3 | bye   |
+----+--------+-----------+-------+

Najpierw usuń wiersze z notatkami o wartości null, w których istnieje wiersz z notatkami innymi niż null.

DELETE c1 FROM cars_drivers AS c1 INNER JOIN cars_drivers AS c2
 ON (c1.driver_id,c1.car_id) = (c2.driver_id,c2.car_id)
WHERE c1.notes IS NULL AND c2.notes IS NOT NULL;

+----+--------+-----------+-------+
| id | car_id | driver_id | notes |
+----+--------+-----------+-------+
|  1 |      1 |         1 | NULL  |
|  2 |      1 |         1 | NULL  |
|  3 |      1 |         2 | NULL  |
|  4 |      1 |         2 | NULL  |
|  8 |      2 |         3 | hi    |
|  9 |      3 |         5 | NULL  |
| 11 |      2 |         3 | bye   |
+----+--------+-----------+-------+

Po drugie, usuń wszystkie wiersze oprócz najwyższego identyfikatora z każdej grupy duplikatów.

DELETE c1 FROM cars_drivers AS c1 INNER JOIN cars_drivers AS c2
 ON (c1.driver_id,c1.car_id) = (c2.driver_id,c2.car_id) AND c1.id < c2.id;

+----+--------+-----------+-------+
| id | car_id | driver_id | notes |
+----+--------+-----------+-------+
|  2 |      1 |         1 | NULL  |
|  4 |      1 |         2 | NULL  |
|  9 |      3 |         5 | NULL  |
| 11 |      2 |         3 | bye   |
+----+--------+-----------+-------+


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak utworzyć zapytanie w MySQL, aby odejmować kolejne wiersze na podstawie daty i wyróżniającego pola?

  2. Symfony2:Lista miast według kraju

  3. Struktura i zapytania systemu przyjaźni

  4. Dynamiczna lista rozwijana PHP MySQL

  5. przygotowana instrukcja, w której wartość jest w tablicy