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 に答える