2016-02-13 55 views
0

中创建递增值我有以下表格:SQL查询组

+----+--------+-----+ 
| id | fk_did | pos | 
+----+--------+-----+ 

此表包含数百行的,他们每个人引用另一个表fk_didpos中的值目前总是为零,我想更改。

基本上,对于fk_did的每个组,pos柱应从零开始并且是递增的。行的排列顺序无关紧要。

实施例输出(select * from table order by fk_did, pos),我想获得:

+----+--------+-----+ 
| id | fk_did | pos | 
+----+--------+-----+ 
| xx |  0 | 0 | 
| xx |  0 | 1 | 
| xx |  0 | 2 | 
| xx |  1 | 0 | 
| xx |  1 | 1 | 
| xx |  1 | 2 | 
| xx |  4 | 0 | 
| xx |  8 | 0 | 
| xx |  8 | 1 | 
| xx |  8 | 2 | 
+----+--------+-----+ 
  • 必须有具有的fk_did相同的组合和pos
  • pos没有两行必须升序对每个fk_did
  • 如果有一行pos> 0,还必须有一行具有相同的fk_did和lo更多pos

这可以通过单个更新查询来完成吗?

+0

插入记录应该用WITH子句非常简单和ROW_NUMBER。 –

回答

2

这可以使用窗口函数做:

update the_table 
    set pos = t.rn - 1 
from (
    select id, 
      row_number() over (partition by fk_id) as rn 
    from the_table 
) t 
where t.id = the_table.id; 

pos的顺序,将会或多或少随机的,因为没有order by,但你说没关系。

这里假定id是唯一的,如果不是,您可以改为使用内部列ctid

1

如果id是你的表的PK,那么你可以使用下面的查询来更新表:

UPDATE mytable 
SET pos = t.rn 
FROM (
    SELECT id, fk_did, pos, 
     ROW_NUMBER() OVER (PARTITION BY fk_did ORDER BY id) - 1 AS rn 
    FROM mytable) AS t 
WHERE mytable.id = t.id 

ROW_NUMBER窗口功能,具有PARTITION BY子句中使用,生成的序列号从1开始为每fk_did切片。

Demo here

0

我建议创建一个临时表,如果id列不是唯一的):

create temp table tmp_table as 
select id, fk_did, row_number() over (partition by fk_did) - 1 pos 
from table_name 

然后截断电流表,然后从临时表