【问题标题】:Inserting data with a window function使用窗口函数插入数据
【发布时间】:2016-07-07 23:34:54
【问题描述】:

我正在寻找如何实现这个答案https://stackoverflow.com/a/6821925/3067762

我有一个名为 window_test 的表:

create table window_test (id int, seq int, data text, primary key (id, seq));

Column |  Type   | Modifiers 
--------+---------+-----------
 id     | integer | not null
 seq    | integer | not null
 data   | text    | 

例如,我希望 seq 为每个 id 自动递增

id |  seq   | data 
---+--------+-----------
 1     1       "whatever1"
 1     2       "whatever2"
 2     1       "whatever3"
 3     1       "whatever4"
 1     3       "whatever5"

我也在尝试使用窗口函数来计算“seq”,同时插入其他数据。要提供我正在使用 CTE 的其他数据:

WITH temp_table (id, data) as ( values (1::int,'whatevertext1'::text))
INSERT INTO window_test (id, seq, data) SELECT id, ROW_NUMBER() OVER(PARTITION BY     id ORDER BY data), data FROM temp_table WHERE id = 1;

查询执行,但问题是在第一次插入后它总是违反 (id,seq) 的唯一约束。我认为这是因为 ROW_NUMBER() 是在我的临时表/CTE 而不是 window_test 上计算的 - 我怎样才能让它使用 window_test 表?

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    嗯,那是因为您每次都从“1”开始。您需要获取现有的最大值以避免此问题。这是一种方法:

    WITH temp_table (id, data) as ( values (1::int,'whatevertext1'::text))
    INSERT INTO window_test (id, seq, data)
        SELECT id,
               (ROW_NUMBER() OVER (PARTITION BY id ORDER BY data) + 
                COALESCE(wt.maxseq, 0)
               ),
               data
        FROM temp_table tt LEFT JOIN
             (SELECT id, MAX(seq) as maxseq
              FROM window_test
              GROUP BY id
             ) wt
             ON tt.id = wt.id
        WHERE id = 1;
    

    【讨论】:

    • 我猜这个需求不是并发安全的?没什么大不了的,它可以满足我的需求,并且该表具有很高的读写比率,并且可以在非工作时间连续进行写入
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 2023-03-11
    • 1970-01-01
    • 2015-02-16
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多