2013-07-16 33 views
21

私はPostgreSQLを使用していましたが、現在はに移行しています。です。 MySQLのでこの文のいずれかの対応があるかどうか私のクエリでPostgresqlからMySQLへのSELECT DISTINCT ONクエリの変換

、私が使用しているPostgreSQLのSELECT DISTINCT ON (col1, col2, col3)は、私は思っていました。

+0

お試しください 3つの組み合わせを区別する必要がある場合は、テーブルからDISTINCT concat(col1、col2、col3)を選択してください –

+1

私はMySQLで "部分的"グループを使用する必要がありますon (他のDBMSには許可されません)これらの3つの列とあなたは非個別の列のための予測不可能な値を取得しているという事実と一緒に暮らします。 –

答えて

26

正確eはありませんquivalentを使用すると、MySQLにSELECT DISTINCT ONを使用するPostgresqlクエリを変換できます。

PostgresqlのSELECT DISTINCT ON PostgreSQLで

、式は(col1, col2, col3)一致、そしてそれだけで一致行の各セットは、「第一COL4、COL5行」を維持するすべての行を排除する次のクエリ。

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

当社Q:

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

は、だからあなたのテーブルには、次のようにある場合ueryは(1,2,3)に対して1行だけを保持し、(3,3,3)に対しては1行だけ保持します。結果の行は、次のようになります。

:各セットの「最初の行は」予測不可能であることを何卒ご了承下さい

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

我々は、ORDER BYを指定しない限り、私たちの拳行が同様に(888、999)であるかもしれません

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

(表現上のDISTINCTが表現BY左端の順序と一致する必要がありますが、ORDER BYは、追加の式を含めることができます)。私達はGROUP BY句で指定されていない非集約列を選択することができるように、MySQLはGROUP BYの使用を拡張し

BY GROUPへ

MySQLの拡張。集約されていない列を選択するたびに、サーバーはその列から各グループの任意の値を自由に選択できるので、結果の値は確定しません。

だから、これはPostgreSQLのクエリ:

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

は、このMySQLのクエリに同等とみなすことができる。

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

PostgreSQLとMySQLの両方が、それぞれ(COL1、COL2のための "最初の行" を返します。 col3)、どちらの場合も、by節を指定していないため、返される行は予測できません。この1と

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

多くの人々は非常に、ORDER BYでこれPostgreSQLのクエリを変換するように誘惑されるだろう

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

ここでの考え方は、に、ORDER BYを適用することですそれはCOL4とCOL5の最初の遭遇値を維持しますCOL3 MySQLはグループCOL1、COL2によって、なるようにサブクエリ。 アイデアは良いですが、間違っています! MySQLはCOL4とCOL5の任意の値を自由に選択することが、私たちは最初に検出した値であるかわからない、それがオプティマイザによって異なります。だから私はこれに修正します:

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 

しかし、これはより複雑になり始めています。一般的なルールとして

結論

、MySQLのクエリにPostgreSQLのクエリを変換する正確な方法はありませんが、回避策がたくさんあり、結果のクエリは、オリジナルのものと同じくらい簡単かもしれません非常に複雑になるかもしれませんが、クエリ自体に依存します。

-4

そのはすでに非推奨とあなたの代わりにMYSQLPDOまたはMSYQLIに移行する必要があります。あなたの質問について

あなたはあなたが複数の列から異なる値を選択することはできません

SELECT DISTINCT col1, col2, col3 

または

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

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

私はあなたの文を好き:「* MYSQLは既に廃止されました*」;) –

+2

は、私はあなたのコメントを愛するあまりにも私を@a_horse_with_no_name :) –

+0

@a_horseを私もそれを好むが、私はそれが意味正確に何についてはよく分かりません。また、私は、彼らはただのインターフェースであるとして 'PDO'かは、' PostgreSQLや他のDBMSを交換mysqli'ないかを確認することはできません。私はそれが悪い言葉遣いだと思う。 –

-2

を行うことができます。使用を選択しながら、この

select distinct col1, col2 from table 
-1

のようなクエリでは、順序、およびグループ化に外側のクエリを決定するために、サブクエリを使用します。

@a_horse_with_no_nameが指摘するように、これは、MySQLが部分的に他のDBMSとは異なり、group byを許可するために機能します。例えば

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') 
; 

は、各顧客の最初の注文のクエリ:

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

結果:

| 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