【问题标题】:How to do INSERT INTO SELECT and ON DUPLICATE UPDATE in PostgreSQL 9.5?如何在 PostgreSQL 9.5 中执行 INSERT INTO SELECT 和 ON DUPLICATE UPDATE?
【发布时间】:2017-02-01 11:05:36
【问题描述】:

我正在尝试在 PostgreSQL 中执行以下操作

INSERT INTO blog_sums ( blog_id, date, total_comments)
    SELECT blog_id, '2016-09-22', count(comment_id) as total_comments_update
    FROM blog_comments
    WHERE date = '2016-09-22'
    GROUP BY blog_id         
ON CONFLICT (blog_id ,date)
DO UPDATE SET blog_sums.total_comments = total_comments_update;

我在 date + blog_id 上有唯一键,但我不断收到错误消息:

错误:列“total_cmets_update”不存在

我正在寻找在这种情况下更新重复/冲突的“正确”方式和最有效的方式

我的桌子是

blog_comments (blog_id, comment_id, comment, date)
blog_sums ( blog_id, date, total_comments) . unique on blog_id+date

谢谢

【问题讨论】:

    标签: postgresql postgresql-9.5


    【解决方案1】:

    您不能从DO UPDATE SET 子句中的选择访问列别名。您可以使用 excluded 表别名,其中包括由于冲突而无法插入的所有行:

    INSERT INTO blog_sums ( blog_id, date, total_comments)
        SELECT blog_id, '2016-09-22', count(comment_id) as total_comments_update
        FROM blog_comments
        WHERE date = '2016-09-22'
        GROUP BY blog_id         
    ON CONFLICT (blog_id ,date)
    DO UPDATE SET total_comments = excluded.total_comments;
    

    所以最后一行中的excluded.total_comments 指的是我们尝试插入但由于冲突而无法插入的total_comments 的值。

    【讨论】:

    • 不要忘记 GROUP BY 否则你会得到(使用 postgresql 9.6.1):错误:ON CONFLICT DO UPDATE 命令不能再次影响行提示:确保没有建议插入的行在同一命令中具有重复的约束值。
    猜你喜欢
    • 2011-01-29
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 2016-10-29
    相关资源
    最近更新 更多