2

次のようなテーブルがあります。

+------+-------+
|ID    | value |
+------+-------+
| 1    | 150   |
| 2    |       |
| 3    |       |
| 4    |       |
| 5    | 530   |
| 6    | 950   |
| 7    | 651   |
+-------+------+

最後の 3 つの値をコピーしたいのですが、最終的にテーブルは次のようになります。

+------+-------+
|ID    | value |
+------+-------+
| 1    | 150   |
| 2    | 530   |
| 3    | 950   |
| 4    | 651   |
| 5    | 530   |
| 6    | 950   |
| 7    | 651   |
+-------+------+

出来ますか?

4

3 に答える 3

8

自己結合を使用します:

UPDATE mytable m
SET    value = m0.value
FROM   mytable m0
WHERE  m.id = (m0.id - 3)   -- define offset
AND    m.id BETWEEN 2 AND 4 -- define range to be affected
AND    m.value IS NULL;     -- make sure only NULL values are updated

ID スペースにギャップがある場合は、windows 関数row_number()を使用してギャップレス ID を取得します。自己結合のためにテーブルを 2 回再利用するため、CTE でこれを行います。

WITH x AS (
   SELECT *, row_number() OVER (ORDER BY ID) AS rn
   FROM   mytable
   )
UPDATE mytable m
SET    value = y.value
FROM   x
JOIN   x AS y ON x.rn = (y.rn - 4567)   -- JOIN CTE x AS y with an offset
WHERE  x.id = m.id                      -- JOIN CTE x to original
AND    m.id BETWEEN 1235 AND 3455
AND    m.value IS NULL;

データ変更 CTEには PostgreSQL 9.1 以降が必要です。

于 2012-11-22T01:26:44.487 に答える
0

ハードコーディングされ3たものは 2 回表示され、必要な数の行に置き換えられます。3最後のレコードに実際に値があると想定しています。これらの値を取得し、null 値を持つ一連のレコードに順番に適用します。

update a
  set value = x.value
  from (

        select nullRows.id, lastRows.value

          from ( select id, value
                       ,(row_number() over(order by id) - 1) % 3 + 1 AS key
                   from ( select id, value
                            from a
                            order by id desc
                            limit 3
                        ) x
                   order by 1

               ) AS lastRows

              ,( select id
                       ,(row_number() over(order by id) - 1) % 3 + 1 AS key
                   from a
                   where value is null
                   order by id

               ) AS nullRows

         where lastRows.key = nullRows.key

      ) x

where a.id = x.id
于 2012-11-22T01:50:18.510 に答える
0

このようなアドホックな更新の場合、おそらく 3 つの単純な更新ステートメントよりも優れた方法はありません。

UPDATE mytable SET value = 530 WHERE id = 2;
UPDATE mytable SET value = 950 WHERE id = 3;
UPDATE mytable SET value = 651 WHERE id = 4;

問題は、これがこの正確なデータにのみ適用されるアドホック更新なのか、それともそのテーブル内のすべての可能なデータに対して実装したい一般的な更新ルールのケースなのかということです。もしそうなら、もっと詳細が必要です。

于 2012-11-22T01:00:34.887 に答える