PHP MySql交换两行的值

时间:2013-04-08 18:55:50

标签: php mysql sql-update

我已经看到了这方面的一些变化,但主要是它们交换整行而不是该行中的一个值,而不是动态。

问题在于:

我有三行,每行包含以下单元格(id,title,content,display_order,visible)。 id是auto_increment。手动输入标题和内容,可见的是切换。 display_order在创建每一行时设置,并自动设置为最高整数并设置在堆栈的底部。

我这样设置,以便如果要手动删除这些记录,我可以自动重新排序堆栈(如果有4条记录,我删除#2,新订单重置为1,2,3而不是1,3,4)。

每一行都有一组向上和向下箭头按钮,它们通过id(id),display_order(pos)和direction(dir)的查询来调用move.php。

在move.php中,它使用条件来确定是否根据方向变量的设置来向上或向下移动记录。

我需要编写哪些PHP代码来获取这三个变量(id,pos,dir)并交换表格单元格中的值display_order:这是一个直观的表示

初​​始:

id   title   pos   
-----------------
 1   slide1   1
 2   slide2   2
 3   slide3   3

点击记录ID#3的UP按钮后:

id   title   pos   
-----------------
 1   slide1   1
 2   slide2   3
 3   slide3   2

明白你的ID和POS并不总是相同的整数

使用davidethell的建议我创建了这个:

这是我创建的内容,但我得到的是echo $ newPos,而不是回到admin.php:

require ("connection.php");
    $id = $_GET['id'];
    $pos = $_GET['pos'];
    $dir = $_GET['dir'];

    if ($dir == 'up') {
        $newPos = $pos-1;
    } else {
        $newPos = $pos+1;
    }

    $fromRow = "SELECT * FROM pages WHERE display_order = ".$pos."";
    $toRow = "SELECT * FROM pages WHERE display_order = ".$newPos."";

    $reord = mysqli_query($conn, "UPDATE pages SET display_order = " . $toRow['display_order'] . " WHERE id = " . $fromRow['id']."; UPDATE pages SET display_order = " . $fromRow['display_order'] . " WHERE id = " . $toRow['id']);

    if ($reord){
        header("Location: admin.php");
    }else{
        echo $newPos;
    }

我遇到的问题是它只回显了$ newPos

更新代码:

require ("connection.php");

    $fromArray = array();
    $toArray = array();

    $id = $_GET['id'];
    $pos = $_GET['pos'];
    $dir = $_GET['dir'];

    if ($dir == 'up') {
        $newPos = $pos-1;
    } else {
        $newPos = $pos+1;
    }

    $fromRow = mysql_query("SELECT * FROM pages WHERE display_order = ".$pos."");

    $toRow = mysql_query("SELECT * FROM pages WHERE display_order = ".$newPos."");


    $reord = mysqli_query($conn, "UPDATE pages SET display_order = " . $toRow['display_order'] . " WHERE id = " . $fromRow['id']);
    $reord = mysqli_query($conn, "UPDATE pages SET display_order = " . $fromRow['display_order'] . " WHERE id = " . $toRow['id']);

    if ($reord){
        header("Location: admin.php");
    }else{
        echo $newPos;
    }

结果:回显$ newPos而不是返回admin.php

3 个答案:

答案 0 :(得分:3)

您可以使用此查询:

UPDATE
  yourtable INNER JOIN (
    SELECT
      MAX(yourtable.pos) pos_prec,
      curr.pos pos_curr
    FROM
      yourtable INNER JOIN
      (SELECT pos FROM yourtable WHERE id=3) curr
      ON yourtable.pos<curr.pos
    GROUP BY
      curr.pos) cp ON yourtable.pos IN (cp.pos_prec, cp.pos_curr)
SET
  pos = CASE WHEN pos=cp.pos_curr
             THEN pos_prec ELSE pos_curr END

它有点复杂,但它会将ID = 3的位置值与前一项的位置值交换,即使存在间隙。

请参阅小提琴here

修改

如果没有间隙,您只需使用它来移动ID#3 UP:

UPDATE
  yourtable INNER JOIN (SELECT pos FROM yourtable WHERE id=3) curr
  ON yourtable.pos IN (curr.pos, curr.pos-1)
SET
  yourtable.pos = CASE WHEN yourtable.pos=curr.pos
                       THEN curr.pos-1 ELSE curr.pos END;

只需使用+1而不是-1来向下移动(如果需要,UP和DOWN都可以组合在一个查询中)。

PHP代码

这是使用PHP和mysqli,并假设给出了位置:

<?php
$mysqli = new mysqli("localhost", "username", "password", "test");

$pos = 3;
$dir = 'down';

if ($dir == 'up') { $newPos = $pos-1; } else { $newPos = $pos+1; }

if ($stmt = $mysqli->prepare("
  UPDATE
    yourtable
  SET
    pos = CASE WHEN yourtable.pos=?
               THEN ?
               ELSE ? END
  WHERE
    pos IN (?, ?)
    AND (SELECT * FROM (
         SELECT COUNT(*) FROM yourtable WHERE pos IN (?,?)) s )=2;"))
{

    $stmt->bind_param("iiiiiii", $pos, $newPos, $pos, $pos, $newPos, $pos, $newPos); 
    $stmt->execute();
    printf("%d Row affected.\n", $stmt->affected_rows);

    $stmt->close();
}
$mysqli->close();
?>

(我还添加了一张支票,如果试图向上移动第一个pos,或者向下移动最后一个pos,它将什么都不做。)

答案 1 :(得分:1)

假设每个行数据都有一个$ row对象,只需执行:

if ($dir == 'up') {
    $fromRow = $row2;
    $toRow = $row1;
}
else {
    $fromRow = $row1;
    $toRow = $row2;
}
$sql = "UPDATE mytable SET pos = " . $toRow['pos'] . " WHERE id = " . $fromRow['id'];
// now execute your SQL however you want in your framework
$sql = "UPDATE mytable SET pos = " . $fromRow['pos'] . " WHERE id = " . $toRow['id'];
// now execute your SQL however you want in your framework

将它放在某种函数或类中以使其可重用。

编辑: 根据您的编辑,您似乎无法在查询中获取足够的信息。他们应该是:

$fromRow = mysql_query("SELECT * FROM pages WHERE display_order = ".$pos."");

$toRow = mysql_query("SELECT * FROM pages WHERE display_order = ".$newPos."");

您只选择了id字段,但之后您尝试使用display_order字段。

答案 2 :(得分:0)

我不会给你写PHP代码。但我会给你SQL:

假设幻灯片的位置应该提高1,则$ delta为+1,如果幻灯片的位置应该降低1,则$ delta为-1。 $ id是幻灯片的ID。我们假设该表名为slides_table。

您需要2个查询:

update slides_table set pos = pos + $delta where id = $id;
update slides_table set pos = pos - $delta where pos = (select pos from slides_table where id=$id) and id != $id