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中文网其他相关文章!