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

Konwersja zapytań SELECT DISTINCT ON z Postgresql do MySQL

Nie ma dokładnego odpowiednika konwersji zapytania Postgresql korzystającego z SELECT DISTINCT ON na MySQL.

Postgresql WYBIERZ WYRÓŻNIENIE NA

W Postgresql poniższe zapytanie wyeliminuje wszystkie wiersze, w których wyrażenia (col1, col2, col3) dopasowania, a dla każdego zestawu dopasowanych wierszy zostanie zachowany tylko wiersz „pierwszy col4, col5”:

SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename

Więc jeśli Twój stół wygląda tak:

col1 | col2 | col3 | col4 | col5
--------------------------------
1    | 2    | 3    | 777  | 888
1    | 2    | 3    | 888  | 999
3    | 3    | 3    | 555  | 555

nasze zapytanie zachowa tylko jeden wiersz dla (1,2,3) i jeden wiersz dla (3,3,3). Wynikowe wiersze będą wtedy wyglądały następująco:

col4 | col5
-----------
777  | 888
555  | 555

proszę zauważyć, że "pierwszy rząd" każdego zestawu jest nieprzewidywalny, nasz pierwszy rząd może być również (888, 999), chyba że określimy ORDER BY:

SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4

(DISTINCT na wyrażeniach musi odpowiadać wyrażeniom ORDER BY znajdującym się najbardziej po lewej stronie, ale ORDER BY może zawierać dodatkowe wyrażenia).

Rozszerzenie MySQL do GROUP BY

MySQL rozszerza użycie GROUP BY, dzięki czemu możemy wybrać niezagregowane kolumny, których nie wymieniono w klauzuli GROUP BY. Za każdym razem, gdy wybieramy kolumny niezagregowane, serwer może swobodnie wybrać dowolną wartość z każdej grupy z tej kolumny, więc wynikowe wartości będą nieokreślone.

Więc to zapytanie Postgresql:

SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename

można uznać za równoważne z tym zapytaniem MySQL:

SELECT col4, col5
FROM tablename
GROUP BY col1, col2, col3

zarówno Postgresql, jak i MySQL zwrócą "Pierwszy wiersz" dla każdego z nich (col1, col2, col3) i w obu przypadkach zwrócony wiersz jest nieprzewidywalny, ponieważ nie określiliśmy i nie uporządkowaliśmy klauzuli.

Wiele osób kusiłoby, aby przekonwertować to zapytanie Postgresql za pomocą ORDER BY:

SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4

z tym:

SELECT col4, col5
FROM (
  SELECT col1, col2, col3, col4, col5
  FROM tablename
  ORDER BY col1, col2, col3, col4
) s
GROUP BY col1, col2, col3

Pomysł polega na tym, aby zastosować ORDER BY do podzapytania, aby kiedy MySQL grupował według col1, col2, col3, zachował pierwszą napotkaną wartość dla col4 i col5. Pomysł jest dobry, ale zły! MySQL może swobodnie wybrać dowolną wartość dla col4 i col5, a nie wiemy, które wartości są pierwszymi napotkanymi, zależy to od optymalizatora. Więc poprawiłbym to do tego:

SELECT t1.col4, t1.col5
FROM tablename t1 INNER JOIN (SELECT col1, col2, col3, MIN(col4) as m_col4
                              FROM tablename
                              GROUP BY col1, col2, col3) s
     ON t1.col1=s.col1
        AND t1.col2=s.col2
        AND t1.col3=s.col3
        AND t1.col4=s.m_col4
GROUP BY
  t1.col1, t1.col2, t1.col3, t1.col4

ale to zaczyna się komplikować.

Wniosek

Zasadniczo nie ma dokładnego sposobu na przekonwertowanie zapytania Postgresql na zapytanie MySQL, ale istnieje wiele obejść, wynikowe zapytanie może być tak proste jak oryginalne lub może stać się bardzo skomplikowane, ale zależy to od samo zapytanie.



  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 przeprowadzić audyt bazy danych PostgreSQL

  2. Podziel dane kolumny oddzielone przecinkami na dodatkowe kolumny

  3. Co dokładnie wyjaśnia PostgreSQL?

  4. Scalanie konkatenacji kolumn JSON(B) w zapytaniu

  5. Jak obliczyć średnią kroczącą w PostgreSQL