我有一张这样的表:
我收到这样的数组:
$data = array(
array('m_id'=>1,'d_id'=>101,'available'=>0),
array('m_id'=>1,'d_id'=>102,'available'=>1),
array('m_id'=>1,'d_id'=>103,'available'=>1),
array('m_id'=>1,'d_id'=>104,'available'=>0),
array('m_id'=>1,'d_id'=>105,'available'=>0)
);
我的问题是如何使用以下一个查询来更新表:
$query = "UPDATE tbl_name SET available='".$data[0]['available']."'" WHERE conditon1";
我的意思是更新表一次而不是5次查询。
答案 0 :(得分:2)
在纯MySQL中,您可以在CASE
中使用UPDATE
表达式来处理此问题:
UPDATE tbl_name
SET available = CASE WHEN d_id = 101 THEN 0
WHEN d_id = 102 THEN 1
WHEN d_id = 103 THEN 1
WHEN d_id = 104 THEN 0
WHEN d_id = 105 THEN 0 END
WHERE d_id IN (101, 102, 103, 104, 105)
另一方面,如果您希望遍历数组数组然后发出UPDATE
语句,则可以尝试以下操作:
foreach ($data as $entry) {
$query = "UPDATE tbl_name SET available=".$entry['available']." WHERE d_id=".$entry['d_id'];
// execute $query ...
}
答案 1 :(得分:1)
this one可能重复。简而言之 - 您需要使用CASE
条件或INSERT ... ON DUPLICATE KEY UPDATE
构造。
答案 2 :(得分:0)
根据您提供的数据,所有行引用相同的列,并始终更新同一列,您可以创建一个简单的CASE
表达式:
/* Mostly untested */
function update_array ($data)
{
if (empty ($data))
return NULL;
if (count ($data) === 1) {
/* Simple query for single update */
$mi = $data[0]['m_id'];
$di = $data[0]['d_id'];
$av = $data[0]['available'];
$sql = <<<_
UPDATE `tbl_name`
SET `available` = $av
WHERE `m_id`= $mi AND `d_id`= $di
_;
} else {
/* CASE WHEN query for multiple updates */
$sql = "UPDATE `tbl_name`\n SET `available` = \n CASE ";
foreach ($data as $d) {
$mi = $d['m_id'];
$di = $d['d_id'];
$av = $d['available'];
$sql .= "WHEN `m_id`=$mi AND `d_id`=$di THEN $av\n ";
}
/* Never forget the ELSE clause! */
$sql .= "ELSE `available`\n END\n";
}
return $sql;
}
此测试程序:
$data = array(
array('m_id'=>1, 'd_id'=>101, 'available'=>0),
array('m_id'=>1, 'd_id'=>102, 'available'=>1),
array('m_id'=>1, 'd_id'=>103, 'available'=>1),
array('m_id'=>1, 'd_id'=>104, 'available'=>0),
array('m_id'=>1, 'd_id'=>105, 'available'=>0)
);
echo update_array ($data);
输出:
UPDATE `tbl_name`
SET `available` =
CASE WHEN `m_id`=1 AND `d_id`=101 THEN 0
WHEN `m_id`=1 AND `d_id`=102 THEN 1
WHEN `m_id`=1 AND `d_id`=103 THEN 1
WHEN `m_id`=1 AND `d_id`=104 THEN 0
WHEN `m_id`=1 AND `d_id`=105 THEN 0
ELSE `available`
END
注意:
从不忘记ELSE
更新中的CASE WHEN
条款。如果这样做,那么所有不匹配的行都将被空值覆盖。
此代码盲目地假设数据包含预期的索引,并且数据属于适当的类型。
有人说你应该包含一个WHERE
子句来限制因性能原因而要更新的行数。我还没有看到任何数据支持这一点,但如果这是一个问题,那么一个简单的改进可能使用d_id
列来缩小范围。只需在CASE WHEN
查询末尾添加以下内容:
$ids = array_column ($data, 'd_id');
$sql .= ' WHERE `d_id` IN (' . implode (', ', $ids) . ")\n";
您仍然需要ELSE
表达式中的CASE
,因为不保证此WHERE
子句不会排除所有不需要的行。编写完整的WHERE
子句可能要复杂得多,具体取决于数据的确切性质。