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']));

如果存在第一个和第二个 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']);
  }
}

重要的!检查存在两条记录,锁定行以进行更新

4

3 回答 3

2

MySQL不支持在 FROM 语句中更新同一张表。因此,因此存在(select * from TBL) as t2内部子查询。

如果第二条记录不存在EXISTS,第一个条件也是防止更新(“如果存在第一条和第二条记录更改订单值”)CASE WHEN

这是一个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

通过一个查询,它是:

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 回答
1

要按行交换 2 个字段,请id尝试:

UPDATE `tbl` AS tbl1
    JOIN `tbl` AS tbl2 ON ( tbl1.id = 33 AND tbl2.id = 34 )
SET
    tbl1.order = tbl2.order, tbl2.order = tbl1.order

您也可以设置所需的值,而不是在 2 个字段之间交换。如果需要,您可以添加如下所示的 where 子句来交换 cat_id1在两行中的位置:

WHERE 
    tbl1.cat_id = 1 AND tbl2.cat_id = 1

更新: 如果您的订单号是唯一的,cat_id您可以尝试以下方式:

UPDATE `tbl` AS tbl1
    JOIN `tbl` AS tbl2 ON ( tbl1.order = 1 AND tbl2.order = 2 )
SET
    tbl1.order = tbl2.order, tbl2.order = tbl1.order
WHERE 
    tbl1.cat_id = 1 AND tbl2.cat_id = 1

如果您的订单字段为 ,则它有效int,否则您应该在查询中引用订单值。

在SQLFiddle上查看结果

于 2013-09-20T08:53:56.520 回答