0

テーブルそれをテストと呼びましょう

 ----------------------------
 |  id  |  catid  |  value  |
 |  1   |    1    |   1     |
 |  2   |    1    |   2     |
 |  3   |    2    |   1     |
 |  4   |    1    |   3     |
 |  5   |    1    |   4     |
 |  6   |    1    |   5     |
 |  7   |    2    |   2     |
 ----------------------------

テーブルから2行目を削除したとします。これで、テーブルは次のようになります。

 ----------------------------
 |  id  |  catid  |  value  |
 |  1   |    1    |   1     |
 |  3   |    2    |   1     |
 |  4   |    1    |   3     |
 |  5   |    1    |   4     |
 |  6   |    1    |   5     |
 |  7   |    2    |   2     |
 ----------------------------

したがってcatid1、には値2はありません。したがって、値は、1,3,4,5、....これまでのところ...になります。

目標連続性が維持されるように、前の値から1を引くように値を更新する必要があります(条件が満たされた場合、つまり削除された値よりも大きい場合、すべての値が1つ上がります)。

コード 削除後、更新クエリを実行しようとしています。

UPDATE     `test` 
SET        `value` = 
      (

         SELECT t.param FROM (

                         SELECT `value`-1 AS  param
                         FROM `test`
                         WHERE          
                         `catid` = 1 AND `value` > 2

                       ) AS t

       ) 
WHERE 
      `catid` = 1
      AND   `value` > 2 

これで、最も内側のクエリは、値が2より大きいすべての行を返しますが、更新では文字列または数値のスカラー値が必要です。

したがって、問題は、更新クエリの対象となる行に関して、最も内側のクエリの値をどのように返すことができるかということです。

たとえば、更新クエリがID 4の行を更新しようとしている場合、最も内側のクエリはvalue同じ行IDの列のみを取得し、それを外側のクエリに返します(1を引いた後)。

これに代替アプローチはありますか?

4

1 に答える 1

1

JOINこのサブクエリを含むそのテーブルは次のようになります。

UPDATE test t1
INNER JOIN
( 
  SELECT 
    id, catid, value - 1 AS value
  FROM test
  WHERE catid = 1
    AND value > 2
) AS t2 ON t1.id = t2.id
SET t1.value = t2.value;

SQLフィドルデモ

ただし、このサブクエリは必要ありません。次のように直接実行できます。

UPDATE test t1
SET value = value - 1
WHERE catid = 1
  AND value > 2;

ただし、id次のようにこれらの値に一致するようにその列を修正する必要がある場合があります。

UPDATE test AS t1
INNER JOIN
(
  SELECT 
    *, 
    (@rownum := @rownum + 1) AS newID
  FROM test, (SELECT @rownum := 0) AS t
  ORDER BY Id
) AS t2 ON t1.id = t2.id
SET t1.id = t2.newId,
    t1.value = CASE 
                 WHEN t1.catid = 1 AND t1.value > 2 THEN t2.value - 1 
                 ELSE t1.value 
               END;

SQLFiddleデモを更新しました。

于 2013-02-02T07:58:23.907 に答える