我在列中有“1,3,6,17”等记录,并使用以下内容删除,例如来自他们的“6”:
$sql = "SELECT SeId, SeCatId FROM series WHERE FIND_IN_SET(:catid,SeCatId)";
$stmt = $dbh->prepare($sql);
$stmt -> bindParam('catid',$id);
$stmt->execute();
$result = $stmt->FetchAll();
foreach($result as $row){
$seid = $row['SeId'];
$ids = explode(",",$row['SeCatId']);
$i = 0;
foreach($ids as $catid) {
if($catid===$id){unset($ids[$i]);}
$i++;
}
$ids = implode(",",$ids);
$sql = "UPDATE series SET SeCatId = :catid WHERE SeId = :id";
$stmt = $dbh->prepare($sql);
$stmt -> bindParam(':catid',$ids);
$stmt -> bindParam(':id',$seid);
$stmt->execute();
}
工作正常,但似乎很复杂。有没有更简单的方法来做同样的事情?
答案 0 :(得分:1)
如果您使用更好的数据库设计,那将很容易。不是将ID存储在逗号分隔的字符串中,而是创建一个新表来处理关联。
series_cat_assoc ( SeId, SeCatId )
使用它,如果一个系列有多个类别,您可以插入多行。这使得创建,更新删除变得容易。例如,从给定系列中删除给定类别:
$sql = "SELECT series_cat_assoc WHERE SeCatId = :catid and SeId = :seid)";
答案 1 :(得分:0)
您可以使用array_diff
并执行类似
$stmt->bindParam(':catid', implode(',', array_diff(explode(",", $row['SeCatId']), array('6')));
但你的问题不是PHP,而是你的SQL架构。你不应该在同一个字段中有“数组”值(阅读database normalization以了解原因)。归一化是为了避免这些问题。您应该有一个单独的模式,其中SeId和SeCatId为列,SeId是您的系列表的外键,SeCatId是一个唯一的整数(不是数组)。
您应该有以下行:
SeId | SeCatId
1 | 1
1 | 3
1 | 6
1 | 7
然后删除一个类别只是一个简单的DELETE
语句问题。
答案 2 :(得分:0)
我不知道在算法上是否有更高效的方式,但根据我对您的代码的理解,您可以使用正则表达式更清晰。替换这个:
foreach($result as $row){
$seid = $row['SeId'];
$ids = explode(",",$row['SeCatId']);
$i = 0;
foreach($ids as $catid) {
if($catid===$id){unset($ids[$i]);}
$i++;
}
$ids = implode(",",$ids);
有了这个:
$ids = str_replace(','.$id.',', ',', $row['SeCatId']);
$ids = preg_replace('/(^|,)('.$id.')(,|$)/', "{$0}{$2}", $ids);
答案 3 :(得分:0)
我强烈强烈建议您使用关联/联结表来存储数据。但有时候,您可能会遇到格式错误的数据库,并且您必须执行此类操作。如果是这样,你可以这样做:
select replace(trim(replace(replace(concat(',', SeCatId, ','), concat(',', 6, ','), ','), ',', ' '), ' ', ',')
这个想法如下:
trim()
删除第一个和最后一个空格您可以在一次更新中执行此操作:
update table t
set SeCatId = replace(trim(replace(replace(concat(',', SeCatId, ','), concat(',', 6, ','), ','), ',', ' '), ' ', ',')
where concat(',', SeCatid, ',') like concat('%,', 6, ',%');