4

id | cat_id | order
33 |   1    |  1
34 |   1    |  2

id | cat_id | order
33 |   1    |  2
34 |   1    |  1

現在4つのクエリを使用しています

$db は、プレースホルダーとインジェクション防御を使用するためのラップ $mysqli です。

ID で最初のレコードを取得する

$curr = $db->q('SELECT id,order,cat_id FROM `tbl` WHERE id`=? FOR UPDATE',
33)->fetch_assoc();

最初のレコードが存在する場合、次のレコードを順序フィールドで検索

if($curr){ 

  $next = $db->q('SELECT id,order FROM `tbl` WHERE `cat_id`=? AND 
  `order`>? ORDER BY `order` LIMIT 1 FOR UPDATE',
  $curr['cat_id'],$curr['order']));

存在する場合、最初と 2 番目の recorn 変更順序の値

  if($prev['id']){

    $db->q("UPDATE `tbl` SET `order`=? WHERE `id`=?",$next['order'],$curr['id']);
    $db->q("UPDATE `tbl` SET `order`=? WHERE `id`=?",$curr['order'],$next['id']);
  }
}

重要!存在する 2 つのレコードをチェックし、更新のために行をロックします

4

3 に答える 3

2

MySQLは、FROM ステートメントで同じテーブルを使用した更新をサポートしていません。このため(select * from TBL) as t2、内部サブクエリがあります。

またEXISTS、最初の条件はCASE WHEN、2 番目のレコードが存在しない場合に更新を防止することです (「1 番目と 2 番目のレコードが存在する場合、順序値が変更されます」)。

ここにSQLfiddleの例があります

UPDATE tbl as t1
SET `order`=
CASE WHEN id = 33 
          and 
      EXISTS (SELECT ID from (select * from TBL) t2  where 
        cat_id=t1.Cat_Id 
        and `order`>t1.`order`
         ORDER BY `order` 
          LIMIT 1) 
      THEN 
        (SELECT `order` from (select * from TBL) t2 where 
        cat_id=t1.Cat_Id 
        and `order`>t1.`order`
         ORDER BY `order` 
          LIMIT 1) 

     WHEN id <>33 THEN
       (SELECT `order` from (select * from TBL) t2 where 
        cat_id=t1.Cat_Id 
        and `order`<t1.`order`
       ORDER BY `order` DESC
       LIMIT 1 ) 
     ELSE `order`

END

where id =33
      or 
      (SELECT ID from (select * from TBL) t2 where 
        cat_id=t1.Cat_Id 
        and `order`<t1.`order`
       ORDER BY `order` DESC
       LIMIT 1) =33
于 2013-09-20T10:05:10.257 に答える
1

1 つのクエリでは次のようになります。

UPDATE 
  `tbl` 
SET 
  `order`=CASE 
    WHEN `order`=2 THEN 1 
    WHEN `order`=1 THEN 2 
  END;
WHERE
  `order` IN (1,2)

または、id の条件の場合:

UPDATE 
  `tbl` 
SET 
  `order`=CASE 
    WHEN `order`=2 THEN 1 
    WHEN `order`=1 THEN 2 
  END;
WHERE
  id = $id
于 2013-09-20T08:46:55.813 に答える