Postgres中SELECT DISTINCT ON (col) *语法是否合法可正常执行?
语法合法性与功能说明
你写的SQL语句是Postgres原生支持的合法语法,无需额外配置即可正常运行,功能符合你的预期:会基于some_col字段去重,每个some_col值仅返回匹配到的第一行的所有列。
SELECT DISTINCT ON (some_col) * FROM my_table
关于旧评论的误区说明
你看到的要求DISTINCT ON必须显式列明字段的旧评论属于误传,Postgres官方语法规则从未有此限制,SELECT *和DISTINCT ON组合使用是完全合规的用法。
唯一需要注意的是:如果不搭配ORDER BY子句,Postgres不会保证每个some_col分组下返回的具体是哪一行,返回结果的行选择是不确定的。这也是为什么业界最佳实践建议搭配ORDER BY使用,通过排序规则明确指定要取每个分组的哪一行,比如要取每个分组下最新创建的行可以写为:
SELECT DISTINCT ON (some_col) * FROM my_table ORDER BY some_col, create_time DESC
MySQL非标准GROUP BY语法迁移方案
你之前在MySQL中使用的非标准SELECT * ... GROUP BY语法,本质就是返回每个分组的任意一行数据,和你当前写的不加ORDER BY的DISTINCT ON语法行为完全一致,可以直接替换实现迁移。
如果原来的MySQL业务逻辑中隐含了取分组内特定行的规则(比如主键最小的行、最新更新的行),只需要在DISTINCT ON的SQL中补充对应的ORDER BY规则即可实现完全对齐的效果,且该写法是Postgres原生支持的标准扩展,比MySQL的非标准GROUP BY语法更可控、可读性更高。
内容的提问来源于stack exchange,提问作者KayakinKoder
相关产品推荐
相关产品推荐

