使用窗口函数插入数据

时间:2016-07-07 23:34:55

标签: sql postgresql

我在寻找如何实现这个答案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表?

1 个答案:

答案 0 :(得分:1)

嗯,那是因为你重新开始#&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;