3

我有一个包含一些数据数据的表“mydata”:

id    name       position
===========================
4     foo        -3 
6     bar        -2 
1     baz        -1
3     knork      -1
5     lift       0
2     pitcher    0

我获取使用排序的表order by position ASC;

位置列值可能是非唯一的(出于某种原因,此处未描述 :-),并用于SELECT.

我想做的事 :

我想通过将唯一位置与不破坏订单的每一行相关联来规范化表格列“位置”。此外,归一化后的最高位置应为-1。

希望得到的表格内容:

id    name       position
===========================
4     foo        -6 
6     bar        -5 
1     baz        -4
3     knork      -3
5     lift       -2
2     pitcher    -1

我尝试了几种方法,但未能实施正确 update的陈述。

我想使用

generate_series( -(select count(*) from mydata), -1) 

是获取位置列的新值的一个很好的起点,但我不知道如何将生成的列数据合并到更新语句中。

希望有人可以帮助我:-)

4

4 回答 4

6

就像是:

with renumber as (
  select id,
         -1 * row_number() over (order by position desc, id) as rn
  from foo
)
update foo
  set position = r.rn
from renumber r
where foo.id = r.id
  and position <> r.rn;

SQLFiddle 演示

于 2013-06-11T06:22:36.327 回答
2

试试这个——

询问:

CREATE TABLE temp
(
      id INT
    , name VARCHAR(10)
    , position INT
)

INSERT INTO temp (id, name, position)
VALUES 
    (4, 'foo', -3),
    (6, 'bar', -2),
    (1, 'baz', -1),
    (3, 'knork', -1),
    (5, 'lift', 0),
    (2, 'pitcher', 0)

SELECT 
      id
    , name
    , position = -ROW_NUMBER() OVER (ORDER BY position DESC, id) 
FROM temp
ORDER BY position

更新:

UPDATE temp
SET position = t.rn
FROM (
    SELECT id, rn = - ROW_NUMBER() OVER (ORDER BY position DESC, id) 
    FROM temp
) t
WHERE temp.id = t.id

输出:

id          name       position
----------- ---------- --------------------
4           foo        -6
6           bar        -5
3           knork      -4
1           baz        -3
5           lift       -2
2           pitcher    -1
于 2013-06-11T06:27:03.193 回答
1

@a_horse_with_no_name 真的很接近事实-谢谢!

UPDATE temp 
  SET position=t.rn 
  FROM (SELECT 
            id, name, 
            -((select count( *) 
          FROM temp)
            +1-row_number() OVER (ORDER BY position ASC)) as rn
        FROM temp) t 
  WHERE temp.id=t.id;

SELECT * FROM temp ORDER BY position ASC;

http://sqlfiddle.com/#!1/d1770/6

于 2013-06-11T11:50:55.573 回答
0
update mydata temp1, (select a.*,@var:=@var-1 sno from mydata a, (select @var:=0) b 
order by position desc, id asc) temp2
set temp1.position = temp2.sno
where temp1.id = temp2.id;
于 2013-06-11T06:21:05.617 回答