SELECTDISTINCTONを使用するPostgresqlクエリをMySQLに変換するのとまったく同じものはありません。
Postgresql SELECT DISTINCT ON
Postgresqlでは、次のクエリにより、式(col1, col2, col3)
が含まれるすべての行が削除されます。 一致し、一致した行の各セットの「最初のcol4、col5行」のみを保持します:
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
したがって、テーブルが次のようになっている場合:
col1 | col2 | col3 | col4 | col5
--------------------------------
1 | 2 | 3 | 777 | 888
1 | 2 | 3 | 888 | 999
3 | 3 | 3 | 555 | 555
このクエリでは、(1,2,3)の場合は1行、(3,3,3)の場合は1行だけが保持されます。結果の行は次のようになります:
col4 | col5
-----------
777 | 888
555 | 555
各セットの「最初の行」は予測できないことに注意してください。ORDERBYを指定しない限り、最初の行も(888、999)になる可能性があります。
SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
(式のDISTINCTは、左端のORDER BY式と一致する必要がありますが、ORDER BYには追加の式を含めることができます)。
GROUPBYへのMySQL拡張
MySQLはGROUPBYの使用を拡張して、GROUPBY句で指定されていない非集計列を選択できるようにします。集約されていない列を選択するときはいつでも、サーバーはその列の各グループから任意の値を自由に選択できるため、結果の値は不確定になります。
したがって、この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)の「最初の行」を返します。どちらの場合も、句を指定して順序付けしなかったため、返される行は予測できません。
多くの人は、このPostgresqlクエリをORDER BY:
で変換したくなるでしょう。SELECT DISTINCT ON (col1, col2, col3) col4, col5
FROM tablename
ORDER BY col1, col2, col3, col4
これで:
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を適用して、MySQLがcol1、col2、col3でグループ化するときに、col4とcol5で最初に検出された値を保持するようにすることです。 アイデアは良いですが、間違っています! 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
しかし、これはより複雑になり始めています。
結論
原則として、PostgresqlクエリをMySQLクエリに変換する正確な方法はありませんが、多くの回避策があり、結果のクエリは元のクエリと同じくらい単純であるか、非常に複雑になる可能性がありますが、クエリ自体。