将MySQL查询转换为PostgreSQL
我有一个疑问:将MySQL查询转换为PostgreSQL,mysql,sql,postgresql,Mysql,Sql,Postgresql,我有一个疑问: DROP TABLE IF EXISTS tmp_table; CREATE TEMPORARY TABLE tmp_table(id int primary key) IGNORE ( SELECT user2role.userid AS userid FROM user2role INNER JOIN users ON users.id=user2role.userid INNER JOIN role ON role.roleid=use
DROP TABLE IF EXISTS tmp_table;
CREATE TEMPORARY TABLE tmp_table(id int primary key)
IGNORE (
SELECT user2role.userid AS userid
FROM user2role
INNER JOIN users ON users.id=user2role.userid
INNER JOIN role ON role.roleid=user2role.roleid
WHERE role.parentrole like 'H1::H2::H3::H4::H5::%')
UNION (
SELECT groupid
FROM groups
WHERE groupid IN (2,3,4));
这个查询最初是用MySQL编写的,它使用了IF NOT EXISTS
,而不是DROP TABLE IF EXISTS
。我更改了该部分,但我不知道如何处理忽略
首先,IGNORE
在做什么
我试着寻找PostgreSQL等价物,但它们似乎都涉及复杂的过程。我必须为此编写一个程序吗?如果我必须写一个,它会是什么样子?我可以用一些PHP代码来模拟IGNORE
?(SQL查询由PHP生成。)您可以在postgres中这样编写。
IGNORE
在这里是不相关的,因为表刚刚被重新创建,并且保证为空。而UNION
保证不会插入重复的行
DROP TABLE IF EXISTS tmp_table;
CREATE TEMP TABLE tmp_table(id int4 primary key);
INSERT INTO tmp_table
SELECT user2role.userid::int4 AS id
FROM user2role
JOIN users ON users.id = user2role.userid
JOIN role ON role.roleid = user2role.roleid
WHERE role.parentrole like 'H1::H2::H3::H4::H5::%'
UNION
SELECT groupid::int4
FROM groups
WHERE groupid in (2,3,4);
如果选择中的副本不能发生,则可以考虑更快的<代码>联合所有,而不是<代码>联合< /COD>。否则,您需要
UNION
来消除可能的重复。阅读。
如果数据集很大,可以考虑在插入之后创建主键。那更快
阅读忽略的on效果
在重新访问页面时,我意识到您在原始代码中提到了(如果不存在)
。
您没有这样说,但只有当原始代码仅在表不存在的情况下创建表时才有意义,这就引入了插入前表不是空的可能性。在这种情况下,IGNORE
是相关的,并且在PostgreSQL中需要一个等效项
这是对你问题的另一种解释
如果不存在,则创建临时表。
对于较旧的版本,我最近发布了一个
CREATE TEMP TABLE IF NOT EXISTS tmp_table(id int4 primary key);
INSERT INTO tmp_table
SELECT x.id
FROM (
SELECT user2role.userid::int4 AS id
FROM user2role
JOIN users ON users.id = user2role.userid
JOIN role ON role.roleid = user2role.roleid
WHERE role.parentrole like 'H1::H2::H3::H4::H5::%'
UNION
SELECT groupid::int4
FROM groups
WHERE groupid in (2,3,4)
) x
LEFT JOIN tmp_table t USING (id)
WHERE t.id IS NULL;
左连接。。。其中t.id为NULL
不包括tmp\u表中可能已经存在的任何id
UNION
进入子select,因此该子句只需应用一次。应该是最快的。
.你会在postgres中这样写。
IGNORE
在这里是不相关的,因为表刚刚被重新创建,并且保证为空。而UNION
保证不会插入重复的行
DROP TABLE IF EXISTS tmp_table;
CREATE TEMP TABLE tmp_table(id int4 primary key);
INSERT INTO tmp_table
SELECT user2role.userid::int4 AS id
FROM user2role
JOIN users ON users.id = user2role.userid
JOIN role ON role.roleid = user2role.roleid
WHERE role.parentrole like 'H1::H2::H3::H4::H5::%'
UNION
SELECT groupid::int4
FROM groups
WHERE groupid in (2,3,4);
如果选择中的副本不能发生,则可以考虑更快的<代码>联合所有,而不是<代码>联合< /COD>。否则,您需要
UNION
来消除可能的重复。阅读。
如果数据集很大,可以考虑在插入之后创建主键。那更快
阅读忽略的on效果
在重新访问页面时,我意识到您在原始代码中提到了(如果不存在)
。
您没有这样说,但只有当原始代码仅在表不存在的情况下创建表时才有意义,这就引入了插入前表不是空的可能性。在这种情况下,IGNORE
是相关的,并且在PostgreSQL中需要一个等效项
这是对你问题的另一种解释
如果不存在,则创建临时表。
对于较旧的版本,我最近发布了一个
CREATE TEMP TABLE IF NOT EXISTS tmp_table(id int4 primary key);
INSERT INTO tmp_table
SELECT x.id
FROM (
SELECT user2role.userid::int4 AS id
FROM user2role
JOIN users ON users.id = user2role.userid
JOIN role ON role.roleid = user2role.roleid
WHERE role.parentrole like 'H1::H2::H3::H4::H5::%'
UNION
SELECT groupid::int4
FROM groups
WHERE groupid in (2,3,4)
) x
LEFT JOIN tmp_table t USING (id)
WHERE t.id IS NULL;
左连接。。。其中t.id为NULL
不包括tmp\u表中可能已经存在的任何id
UNION
进入子select,因此该子句只需应用一次。应该是最快的。
.哦,那么忽略下面的内容只是插入到新的临时表中?在这种情况下,为什么要使用ignore而不是insert-into?我不得不猜测。它在mySQL中可能很有用,但在postgres中不需要(也不存在)。关键字IGNORE
有一些副作用,比如将重复的键错误视为警告。但这不能在这里发生,因为每个定义的UNION
消除了重复。非常感谢,有两个简单的问题,为什么要将int改为int 4,将内部连接改为JOIN(这是因为默认情况下JOIN是内部的,所以不重要?internal JOIN
和JOIN
都是。我喜欢简短的版本。添加了cast::int4
,因为问题没有告诉我们类型userid
和groupid
。如果这些已经是整数,您可以把它排除在外。我拒绝了编辑,因为这是正确的:“如果在选择中不存在重复,则可以考虑联合所有”。只有在保证开始时没有重复项的情况下,您才能使用更快的UNION ALL
。否则,您必须使用联合
来消除重复。我澄清了文本。哦,那么忽略下面的内容只是插入到新的临时表中?在这种情况下,为什么要使用ignore而不是insert-into?我不得不猜测。它在mySQL中可能很有用,但在postgres中不需要(也不存在)。关键字IGNORE
有一些副作用,比如将重复的键错误视为警告。但这不能在这里发生,因为每个定义的UNION
消除了重复。非常感谢,有两个简单的问题,为什么要将int改为int 4,将内部连接改为JOIN(这是因为默认情况下JOIN是内部的,所以不重要?internal JOIN
和JOIN
都是。我喜欢简短的版本。添加了cast::int4
,因为问题没有告诉我们类型userid
和groupid
。如果这些已经是整数,您可以把它排除在外。我拒绝了编辑,因为这是正确的:“如果在选择中不存在重复,则可以考虑联合所有”。只有在保证开始时没有重复项的情况下,您才能使用更快的UNION ALL
。否则,您必须使用联合
来消除重复。我澄清了文本。