PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

GROUP lub DISTINCT po JOIN zwraca duplikaty

Podczas pobierania wszystkich lub większości wierszy z tabeli najszybszym sposobem dla tego typu zapytań jest zazwyczaj agregacja/ujednoznacznienie pierwszy i dołącz później :

SELECT *
FROM   products p
JOIN  (
   SELECT DISTINCT ON (product_id) *
   FROM   meta
   ORDER  BY product_id, id DESC
   ) m ON m.product_id = p.id;

Więcej wierszy w meta na wiersz w products , tym większy wpływ na wydajność.

Oczywiście będziesz chciał dodać ORDER BY klauzula w podzapytaniu definiuje które wiersz do wybrania z każdego zestawu w podzapytaniu. @Craig i @Clodoaldo już ci o tym powiedzieli. Zwracam meta wiersz z najwyższym id .

Skrzypce SQL.

Szczegóły dla DISTINCT ON :

  • Wybrać pierwszy wiersz w każdej grupie GROUP BY?

Optymalizuj wydajność

Jednak nie zawsze jest to najszybsze rozwiązanie. W zależności od dystrybucji danych istnieją różne inne style zapytań. W tym prostym przypadku z innym złączeniem, ten przebiegł znacznie szybciej w teście z dużymi tabelami:

SELECT p.*, sub.meta_id, m.product_id, m.price, m.flag
FROM  (
   SELECT product_id, max(id) AS meta_id
   FROM   meta
   GROUP  BY 1
   ) sub
JOIN meta     m ON m.id = sub.meta_id
JOIN products p ON p.id = sub.product_id;

Jeśli nie użyjesz nieopisowego id jako nazwy kolumn, nie napotkalibyśmy kolizji nazw i moglibyśmy po prostu napisać SELECT p.*, m.* . (Ja nigdy użyj id jako nazwę kolumny.)

Jeśli wydajność jest Twoim najważniejszym wymaganiem, rozważ więcej opcji:

  • MATERIALIZED VIEW ze wstępnie zagregowanymi danymi z meta , jeśli Twoje dane się nie zmieniają (znacznie).
  • rekurencyjne CTE emulujące luźne skanowanie indeksu dla dużego meta stół z wieloma wierszy na produkt (stosunkowo kilka odrębnych product_id ).
    To jedyny znany mi sposób na użycie indeksu dla zapytania DISTINCT dla całej tabeli.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nie można połączyć się z lokalnym PostgreSQL

  2. Co nowego w Postgres-XL 9,6

  3. Łączenie wyników z dwóch oddzielnych baz danych

  4. Aktualny stan zarządzania kopiami zapasowymi Open Source dla PostgreSQL

  5. PostGIS w akcji