我有一个像这样的sql表

|[id]--|--[    colour    ]|
|[ 1]--|--[red_blue_green]|
|[ 2]--|--[ green_orange ]|
|[ 3]--|--[  pink_green  ]|
|[ 4]--|--[     green    ]|


我想要做的是从颜色中去除绿色,为此我尝试了

<?php
$del='green';
//DATABASE
require('config.php');
require('connect.php');
$db_content = mysql_query("SELECT * FROM colours WHERE colour LIKE '%_".$del."' OR colour LIKE '%_".$del."_%' OR colour LIKE '".$del."_%' OR colour='$del'");
$rows  = mysql_fetch_row($db_content);
foreach($rows as $row){
  $kaboom = explode('_', $row[6]);
  $i=0;

  while($kaboom[$i]!=$del){
    $i++;
  }

  unset($kaboom[$i]);

  $db_newcontent = implode('_', $kaboom);
  mysql_query("UPDATE colours SET colour='$db_newcontent' WHERE         id='{$row[0]}'");
}


但这是行不通的。它没有任何错误信息,只花了很多时间,然后停止尝试。有什么建议么?

最佳答案

一条SQL语句是可能的。

以下代码(假设您的表称为color)将表与一对子查询交叉连接,每个子查询均返回数字0到9。这将为每行提供100个副本,数字为0到99。然后使用该数字为了找出每种颜色,WHERE子句排除了“绿色”的颜色,然后使用GROUP_CONCAT将它们重新连接在一起。

UPDATE colour a
INNER JOIN
(
    SELECT id, GROUP_CONCAT(DISTINCT colours SEPARATOR '_') AS colour
    FROM
    (
        SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(colour, '_', tens.aCnt * 10 + units.aCnt + 1), '_', -1) AS colours
        FROM colour
        CROSS JOIN
        (
            SELECT 1 AS aCnt UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0
        ) units
        CROSS JOIN
        (
            SELECT 1 AS aCnt UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0
        ) tens
        WHERE FIND_IN_SET('green', REPLACE(colour, '_', ','))
    ) sub0
    WHERE colours != 'green'
    GROUP BY id
) b
ON a.id = b.id
SET a.colour = b.colour


但是,在关系数据库中使用分隔字段通常是一个非常糟糕的主意。例如,如果要搜索列表中绿色为绿色的任何记录,则不能使用索引。数据库将需要检查每条记录。您可以轻松地将它们拆分到一个单独的表中,该表在主表上的每个记录都有多行(每种颜色在主表上的每个引用一个颜色)。您可以使用表联接轻松获得所有值,也可以使用将使用索引的查询轻松检查特定值。

编辑

如果您确实必须使用带分隔符的列,并且想要坚持使用原始解决方案,那么可以使用以下解决方案:

<?php
$del='green';
//DATABASE
require('config.php');
require('connect.php');
$db_content = mysql_query("SELECT id, colour
                            FROM colours
                            WHERE FIND_IN_SET('".mysql_real_escape_string($del)."', REPLACE(colour, '_', ','))");
while ($rows  = mysql_fetch_assoc($db_content))
{
    $kaboom = explode('_', $rows['colour']);
    unset($kaboom[array_search($del, $kaboom)]);

    $db_newcontent = implode('_', $kaboom);
    mysql_query("UPDATE colours
                    SET colour = '".mysql_real_escape_string($db_newcontent)."'
                    WHERE id = ".(int)$rows[0]."");
}


再次编辑

标准化此示例。

您有一个(假设)用户表。它具有id字段:

CREATE TABLE users
(
    id INT(11) NOT NULL AUTO_INCREMENT,
    user_name   VARCHAR(50),
    PRIMARY KEY (`id`),
    UNIQUE KEY `user_name` (`user_name`)
);

INSERT INTO users(id, user_name) VALUES
(1, 'Fred'),
(2, 'Freda'),
(3, 'Jo'),
(4, 'Joe');


然后,您将获得每个用户的颜色表。每个用户每种颜色(或他们键入的任何内容)都有一行:-

CREATE TABLE user_colours
(
    id INT(11) NOT NULL AUTO_INCREMENT,
    user_id INT(11) NOT NULL,
    colour  VARCHAR(50),
    PRIMARY KEY (`id`),
    KEY `user_id` (`user_id`),
    KEY `colour` (`colour`)
);

INSERT INTO user_colours(id, user_id, colour) VALUES
(1, 1, 'red'),
(2, 1, 'blue'),
(3, 1, 'green'),
(4, 2, 'green');
(5, 2, 'orange');
(6, 3, 'pink');
(7, 3, 'green');
(8, 4, 'green');


这样,如果您需要为用户添加额外的颜色,则只需找到该用户的ID,然后在第二个表中插入一条记录即可。例如,如果您想为Freda添加粉红色,则将获得Freda的ID为2,然后在第二个表中插入一行,例如INSERT INTO user_colours(id,user_id,colour)VALUES(NULL,2,'pink') 。

如果您需要删除它,则可以使用DELETE FROM user_colours WHERE user_id = 2 AND color ='pink'轻松完成

如果您想统计每种颜色有多少用户,可以执行以下操作:

SELECT colour, COUNT(user_id)
FROM user_colours
GROUP BY colour

关于php - 更新SQL多行以删除字符串的一部分,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38201790/

10-09 06:08
查看更多