sql >> データベース >  >> RDS >> PostgreSQL

SELECTDISTINCTONクエリをPostgresqlからMySQLに変換する

    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クエリに変換する正確な方法はありませんが、多くの回避策があり、結果のクエリは元のクエリと同じくらい単純であるか、非常に複雑になる可能性がありますが、クエリ自体。



    1. Oracleデータベースにすべてのストアドプロシージャを一覧表示する方法

    2. notifyDataSetChanged()のWinDeath

    3. MultipleActiveResultSets =Trueまたは複数の接続?

    4. 単一のexecSQLクエリで指定できるSQL変数の制限は何ですか