我有一个带有一些数据数据的表“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)
是获取position列的新值的一个很好的起点,但我不知道如何将生成的列数据合并到update语句中。
希望有人可以帮助我: - )答案 0 :(得分: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;
答案 1 :(得分: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
答案 2 :(得分: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;
答案 3 :(得分: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;