2013-07-16 14 views
21

Ich habe PostgreSQL verwendet und jetzt auf MySQL migriert.Konvertierung von SELECT DISTINCT ON Abfragen von Postgresql nach MySQL

In meinen Fragen, ich bin mit PostgreSQL ‚s SELECT DISTINCT ON (col1, col2, col3), ich frage mich, ob es in MySQL jedes Gegenstück dieser Aussage ist.

+0

Sie können versuchen 'Wählen Sie DISTINCT concat (col1, col2, col3) aus der Tabelle' wenn Sie die Kombination der drei zu unterscheiden brauchen –

+1

Ich denke, in MySQL müssen Sie eine "partielle" 'Gruppe von 'auf diese drei Spalten (die in keinem anderen DBMS erlaubt wären) und leben mit der Tatsache, dass Sie unvorhersehbare Werte für die nicht-distinkten Spalten erhalten. –

Antwort

26

Es gibt keine exakte e um eine Postgresql-Abfrage zu konvertieren, die SELECT DISTINCT ON zu MySQL verwendet.

Postgresql SELECT DISTINCT ON

In Postgresql, die folgende Abfrage werden alle Zeilen eliminieren, wo die Ausdrücke (col1, col2, col3) Spiel, und es wird die „erste col4, COL5 Zeile“ für jeden Satz von entsprechenden Datensätze nur halten:

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

Also, wenn Ihr Tisch ist wie folgt:

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

unsere q Sie behalten nur eine Zeile für (1,2,3) und eine Zeile für (3,3,3).Die resultierenden Zeilen werden dann:

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

beachten Sie bitte, dass die „erste Reihe“ jeden Satz unberechenbar ist, unsere Faust Reihe könnte (888, 999) sein, wie gut es sei denn wir einen Auftrag angeben VON:

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

(die DISTINCT-Ausdrücke müssen mit den äußersten linken ORDER BY-Ausdrücken übereinstimmen, aber ORDER BY kann zusätzliche Ausdrücke enthalten).

MySQL-Erweiterung zu GROUP BY

MySQL erweitert die Verwendung von GROUP BY, so dass wir in der GROUP BY-Klausel nicht genannt nicht aggregierten Spalten auswählen können. Immer wenn wir nicht aggregierte Spalten auswählen, kann der Server einen beliebigen Wert aus jeder Gruppe aus dieser Spalte auswählen, sodass die resultierenden Werte unbestimmt sind.

Also diese Postgresql Abfrage:

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

kann äquivalent zu dieser MySQL-Abfrage in Betracht gezogen werden:

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

beide Postgresql und MySQL wird die "Erste Reihe" Rückkehr für jede (col1, col2, col3), und in beiden Fällen ist die zurückgegebene Zeile unvorhersehbar, weil wir keine by-Klausel angegeben haben.

Viele Leute sehr versucht sein, würde diese Postgresql Abfrage mit einer ORDER BY zu konvertieren: hier wird

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

die Idee, um einen Auftrag zu bewerben BY:

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

mit dieser eine Unterabfrage, so dass, wenn MySQL durch col1, col2, col3 gruppiert wird, der erste gefundene Wert für col4 und col5 beibehalten wird. Die Idee ist gut, aber es ist falsch! MySQL kann einen beliebigen Wert für col4 und col5 frei wählen, und wir wissen nicht, welche die ersten Werte sind, es hängt vom Optimierer ab. Also würde ich es korrigieren:

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 

aber das wird immer komplizierter.

Fazit

In der Regel gibt es keine genaue Art und Weise eine Postgresql Abfrage in einer MySQL-Abfrage zu konvertieren, aber es gibt eine Menge von Abhilfen, könnte die resultierende Abfrage so einfach sein wie das Original oder es wird sehr kompliziert, aber es hängt von der Abfrage selbst ab.

-4

Sie sollten PDO wandern oder MSYQLI statt MYSQL als bereits veraltet.

über Ihre Frage können Sie tun

SELECT DISTINCT col1, col2, col3 

oder

SELECT col1, col2, col3 
    ........ 

    GROUP BY col1 --//--- or whatever column you want to be distinct 
+3

Ich mag Ihre Aussage: "* MYSQL ist schon veraltet *";) –

+2

@a_horse_with_no_name ich auch ich liebe deinen Kommentar :) –

+0

@a_horse Obwohl ich es auch mag bin ich mir nicht sicher was genau es bedeutet. Auch kann ich nicht sehen, wie "PDO" oder "mysqli" postgresql oder irgendwelche anderen dbms ersetzen, da sie nur Schnittstellen sind. Ich denke, es ist nur eine schlechte Formulierung. –

-2

Sie können keine unterschiedlichen Werte aus mehreren Spalten auswählen. Verwendung Abfrage wie folgt

select distinct col1, col2 from table 
-1

Verwenden einer Unterabfrage während der Auswahl die Reihenfolge zu bestimmen, und eine äußere Abfrage zu gruppieren.

Wie @a_horse_with_no_name darauf hinweist, funktioniert dies, weil MySQL im Gegensatz zu anderen DBMS teilweise group by erlaubt.

Zum Beispiel:

CREATE TABLE customer_order 
    (`customer` varchar(5), `item` varchar(6), `date` datetime) 
; 

INSERT INTO customer_order 
    (`customer`, `item`, `date`) 
VALUES 
    ('alice', 'widget', '2000-01-05 00:00:00'), 
    ('bob', 'widget', '2000-01-02 00:00:00'), 
    ('alice', 'widget', '2000-01-01 00:00:00'), 
    ('alice', 'wodget', '2000-01-06 00:00:00') 
; 

Abfrage für jeden erste Bestellung des Kunden:

select * 
from 
    (select customer, item, date 
    from customer_order 
    order by date) c 
group by customer 

Ergebnis:

| CUSTOMER | ITEM |       DATE | 
|----------|--------|--------------------------------| 
| alice | widget | January, 01 2000 00:00:00+0000 | 
|  bob | widget | January, 02 2000 00:00:00+0000 | 

http://sqlfiddle.com/#!2/6cbbe/1