求PostgreSQL中与指定MySQL分组查询等价的SQL语句及适配建表语句
PostgreSQL 等价建库、建表及查询语句(对应MySQL原语句)
我帮你把MySQL环境下的建库、建表和查询语句转换成了PostgreSQL的等价版本,确保查询结果和原MySQL语句完全一致,具体内容如下:
1. 建库与切换数据库
PostgreSQL创建数据库的语法和MySQL类似,但切换数据库要用\c命令替代MySQL的use:
CREATE DATABASE IF NOT EXISTS lemonade; \c lemonade; -- 切换到lemonade数据库
2. 建表语句
PostgreSQL中没有auto_increment关键字,推荐使用GENERATED ALWAYS AS IDENTITY实现自增主键;外键语法和MySQL基本一致:
CREATE TABLE users ( id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY, name varchar(50) NOT NULL, email varchar(50) NOT NULL ); CREATE TABLE memories ( id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY, content varchar(50) NOT NULL, userID int REFERENCES users(id) -- 外键约束写法和MySQL一致 );
3. 数据插入语句
PostgreSQL推荐用单引号包裹字符串(双引号也支持,但单引号更符合SQL标准),插入逻辑和MySQL完全一致:
INSERT INTO users (name, email) VALUES ('Ruan', 'ruan@gmail.com'); INSERT INTO users (name, email) VALUES ('Pereira', 'pereira@gmail.com'); INSERT INTO memories (content, userID) VALUES ('memoria 1', 1); INSERT INTO memories (content, userID) VALUES ('memoria 2', 1); INSERT INTO memories (content, userID) VALUES ('memoria 3', 2); INSERT INTO memories (content, userID) VALUES ('memoria 4', 2);
4. 等价查询语句
MySQL的ANY_VALUE是用来绕过ONLY_FULL_GROUP_BY的严格检查,取分组内任意一条记录。PostgreSQL没有这个函数,我们可以用两种方式实现相同效果:
方式一:使用聚合函数(和MySQL ANY_VALUE效果完全匹配)
用MIN()或MAX()聚合函数取分组内的任意值,结果和原MySQL查询一致:
SELECT MIN(m.id) AS memory_id, MIN(m.content) AS memory_content, m.userID, MIN(u.id) AS user_id, MIN(u.name) AS user_name, MIN(u.email) AS user_email FROM memories m INNER JOIN users u ON m.userID = u.id GROUP BY m.userID;
方式二:使用PostgreSQL特有的DISTINCT ON(更高效)
这是PostgreSQL专属语法,能精准获取每个userID分组下的第一条记录(按m.id排序),结果同样符合要求:
SELECT DISTINCT ON (m.userID) m.id, m.content, m.userID, u.id, u.name, u.email FROM memories m INNER JOIN users u ON m.userID = u.id ORDER BY m.userID, m.id;
内容的提问来源于stack exchange,提问作者Ruan Nawe
相关产品推荐
相关产品推荐

