2016-02-13 51 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 

然後截斷電流表,然後從臨時表