PostgreSQL と MySQL の GROUP BY ステートメントの違い
はじめに
MySQL から PostgreSQL にクエリを移行するとき、GROUP BY 句を使用するとエラーが発生することがよくあります。この記事では、MySQL と PostgreSQL の GROUP BY の違いを詳しく説明し、このエラーを解決する方法を説明します。
エラー
PostgreSQL で次のクエリを実行する場合:
<code class="language-sql">SELECT `availables`.* FROM `availables` INNER JOIN `rooms` ON `rooms`.id = `availables`.room_id WHERE (rooms.hotel_id = 5056 AND availables.bookdate BETWEEN '2009-11-22' AND '2009-11-24') GROUP BY availables.bookdate ORDER BY availables.updated_at</code>
PostgreSQL は次のエラーを返す場合があります:
<code>ERROR: column "availables.id" must appear in the GROUP BY clause or be used in an aggregate function</code>
違い
MySQL では、GROUP BY 句を使用して、特定の非集計フィールドをクエリ結果に含めることができます。ただし、PostgreSQL は SQL 標準に従っており、すべての非集計フィールドは GROUP BY 句に指定するか、集計関数で使用する必要があります。
解決策: DISTINCT ON
PostgreSQL で MySQL の GROUP BY 動作をシミュレートするには、DISTINCT ON 式を使用できます。 DISTINCT ON を使用すると、指定された列に基づいてグループごとに一意の行を選択できます。指定された例では、次のクエリは PostgreSQL で機能します:
<code class="language-sql">SELECT DISTINCT ON (availables.bookdate) `availables`.* FROM `availables` INNER JOIN `rooms` ON `rooms`.id = `availables`.room_id WHERE (rooms.hotel_id = 5056 AND availables.bookdate BETWEEN '2009-11-22' AND '2009-11-24') ORDER BY availables.bookdate, availables.updated_at</code>
このクエリは、availables.bookdate の一意の値ごとに 番目の行 を返し、MySQL の GROUP BY 動作を効果的にシミュレートします。 一貫した結果を保証するために、availables.updated_at
が常に同じ行を選択するように ORDER BY
を DISTINCT ON
句に追加しました。 これを行わないと、DISTINCT ON
は実行されるたびに異なる行を返す可能性があります。
以上がMySQL GROUP BY クエリを PostgreSQL に正しく移行するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。