这是我正在尝试编写的查询的简化版本。它旨在将一行保存为变量name
,然后将combine
存储在media_hashtags表中,如果存在特定条目,则INSERT该条目。
UPDATE
然而,我收到此错误:
WITH
combine AS (
SELECT * FROM hashtags WHERE hashtag_text='HOPPA'
)
UPDATE media_hashtags SET hashtag_id = (SELECT id FROM combine) WHERE user_id = 58 AND media_id=161;
INSERT INTO media_hashtags (media_id, user_id, hashtag_id)
SELECT 161, 58, (SELECT id FROM combine)
WHERE NOT EXISTS (
SELECT * FROM media_hashtags
WHERE (
user_id = 58 AND
media_id = 161
)
)
RETURNING *
有趣的是,如果我只使用ERROR: relation "combine" does not exist
LINE 8: SELECT 161, 58, (SELECT id FROM combine)
或仅使用UPDATE
命令进行查询,则会按预期执行。只有在我同时执行这两项操作时才会出现错误。关于问题是什么和修复的任何想法?
答案 0 :(得分:1)
您可以使用临时表来存储来自主题标签的数据,然后插入和更新操作。
这是方法:
DROP TABLE IF EXISTS temp_hashtags;
CREATE TEMP TABLE temp_hashtags AS
SELECT * FROM hashtags WHERE hashtag_text='HOPPA';
UPDATE media_hashtags
SET hashtag_id = (SELECT id FROM temp_hashtags)
WHERE user_id = 58 AND media_id=161;
INSERT INTO media_hashtags (media_id, user_id, hashtag_id)
SELECT 161, 58, (SELECT id FROM temp_hashtags)
WHERE NOT EXISTS (
SELECT * FROM media_hashtags
WHERE user_id = 58 AND media_id = 161
);
答案 1 :(得分:1)
您有两个查询,第一个查询以;
语句之后的UPDATE
结尾。以下INSERT
不再看到CTE,因为它是一个新的声明。
如果您想将此作为单个语句运行,则需要将UPDATE
移入其自己的CTE中:
WITH combine AS (
SELECT id
FROM hashtags
WHERE hashtag_text='HOPPA'
), changed AS (
UPDATE media_hashtags
SET hashtag_id = (SELECT id FROM combine)
WHERE user_id = 58
AND media_id=161
)
INSERT INTO media_hashtags (media_id, user_id, hashtag_id)
SELECT 161, 58, (SELECT id FROM combine)
WHERE NOT EXISTS (
SELECT * FROM media_hashtags
WHERE (
user_id = 58 AND
media_id = 161
)
)
RETURNING *;
您还应该只选择初始CTE中需要的列。后续语句仅使用combine
中的单个列的事实不会被推送到第一个查询中,因此Postgres可能不会尽可能高效地查询hashtags
。
如果您使用的是Postgres 9.5,则可以使用on conflict
语句的insert
子句简化语句:
INSERT INTO media_hashtags (media_id, user_id, hashtag_id)
SELECT 161, 58, id
FROM hashtags
WHERE hashtag_text='HOPPA'
ON CONFLICT (media_id, user_id) DO UPDATE
SET hashtag_id = excluded.hashtag_id;
这需要media_hashtags(media_id, user_id)