Вы бы написали так в 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);
Если дубликаты в SELECT не могут появиться, вы можете рассмотреть более быстрый UNION ALL
вместо UNION
. В противном случае вам нужно UNION
, чтобы устранить возможные ошибки. Читайте здесь .
Если ваш набор данных большой, вы можете рассмотреть возможность создания первичного ключа после ВСТАВКИ. Это быстрее
Прочитайте mySQL документ о влиянии IGNORE
.
При повторном посещении страницы я понял, что вы упоминаете IF NOT EXISTS
в исходном коде.
Вы не говорите так, но это имеет смысл, только если исходный код создал таблицу только в том случае, если она еще не существовала, что создает возможность того, что она будет не пустой до INSERT. В этом случае IGNORE
является релевантным и нуждается в эквиваленте в PostgreSQL.
Итак, вот альтернативный ответ для такой интерпретации вашего вопроса.
CREATE TEMP TABLE IF NOT EXISTS
было реализовано в PostgreSQL 9.1 .
Для более старой версии я недавно опубликовал решение на SO.
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;
LEFT JOIN ... WHERE t.id IS NULL
исключает любые id
, которые могут уже присутствовать в tmp_table
. UNION
входит в подвыбор, так что предложение нужно применять только один раз. Должно быть быстрее всего.
Подробнее о левом присоединении здесь .