更新MySQL表的特定记录

时间:2012-03-07 07:33:08

标签: php mysql

我正在处理电话系统,必须与多家服务供应商合作。对于一个供应商,我有一个像这样的MySQL表country_codes -

---------------------------------------------------------
country_code  |  area_code  |  country
---------------------------------------------------------
93            |  93         |  Afghanistan
0             |  9375       |  Afghanistan Cellular-AT
0             |  9370       |  Afghanistan Cellular-AWCC
355           |  355        |  Albania
0             |  35568      |  Albania Cellular-AMC
0             |  35567      |  Albania Cellular-Eagle
213           |  213        |  Algeria
0             |  21377      |  Algeria Cellular-Djezzy
0             |  2135       |  Algeria Cellular-Wataniya
---------------------------------------------------------

依旧......

country_code列之前没有,但我添加了它,因为我需要它用于我的PHP应用程序。我设法更新了一些记录的国家/地区代码(使用我上一个问题的回答)

我想要实现的是用相应的国家代码替换0。所以表格看起来应该是这样的 -

---------------------------------------------------------
country_code  |  area_code  |  country
---------------------------------------------------------
93            |  93         |  Afghanistan
93            |  9375       |  Afghanistan Cellular-AT
93            |  9370       |  Afghanistan Cellular-AWCC
355           |  355        |  Albania
355           |  35568      |  Albania Cellular-AMC
355           |  35567      |  Albania Cellular-Eagle
213           |  213        |  Algeria
213           |  21377      |  Algeria Cellular-Djezzy
213           |  2135       |  Algeria Cellular-Wataniya
---------------------------------------------------------

我希望我能够很好地解释自己。知道我怎么能用PHP-MySQL做到这一点?

(我不介意使用PHP代码以这种方式操作表)

5 个答案:

答案 0 :(得分:6)

尝试此查询 -

UPDATE country_codes
SET country_code := @c := IF(@c IS NOT NULL AND country_code = 0, @c, country_code)
ORDER BY CAST(area_code AS CHAR)

答案 1 :(得分:2)

update cc set
    country_code = t.country_code
from country_codes cc
join (
    select country_code, country, char_length(trim(cast(country_code as char))) as code_len
    from country_codes
    where country_code <> 0
) t on 
    t.country_code = cast(substr(cast(cc.area_code as char), 1, t.code_len) as signed integer) and
    cc.country_code = 0 and
    cc.country like concat(t.country, '%')

我已将cc.country like concat(t.country, '%')添加到条件更具体但它假设每个蜂窝网络名称都以其国家/地区名称开头 - 所以如果不是这样,请省略它。

@Sachyn评论后

添加

SQLZOO上使用的测试代码运行正常,仅供测试,不是更新查询

select cc.*, t.country_code as new_country_code
from (
    select 93 as country_code, 93  as area_code , 'Afghanistan' as country union
    select 0  , 9375 , 'Afghanistan Cellular-AT' union
    select 0  , 9370 , 'Afghanistan Cellular-AWCC' union
    select 355, 355  , 'Albania' union
    select 0  , 35568, 'Albania Cellular-AMC' union
    select 0  , 35567, 'Albania Cellular-Eagle' union
    select 213, 213  , 'Algeria' union
    select 0  , 21377, 'Algeria Cellular-Djezzy' union
    select 0  , 2135 , 'Algeria Cellular-Wataniya'
) cc
join (
    select country_code, country, char_length(rtrim(cast(country_code as char))) as code_len
    from (
        select 93 as country_code, 93  as area_code , 'Afghanistan' as country union
        select 0  , 9375 , 'Afghanistan Cellular-AT' union
        select 0  , 9370 , 'Afghanistan Cellular-AWCC' union
        select 355, 355  , 'Albania' union
        select 0  , 35568, 'Albania Cellular-AMC' union
        select 0  , 35567, 'Albania Cellular-Eagle' union
        select 213, 213  , 'Algeria' union
        select 0  , 21377, 'Algeria Cellular-Djezzy' union
        select 0  , 2135 , 'Algeria Cellular-Wataniya'
    ) c
    where country_code <> 0
) t on 
    t.country_code = cast(substr(cast(cc.area_code as char), 1, t.code_len) as signed integer) and
    cc.country_code = 0 and
    cc.country like concat(t.country, '%')

答案 2 :(得分:1)

如果您只需要修复一次数据,您可以尝试这种方法:

0)备份您的数据,或者更好,在数据副本上运行查询。

1)创建一个包含非零国家/地区代码的表。我们需要单独的表,因为它在MySQL手册中说:

  

目前,您无法更新表并从中选择同一个表   子查询。

CREATE TABLE country_codes_list (
    country_code INT NOT NULL PRIMARY KEY
);

INSERT INTO country_codes_list
SELECT country_code
FROM country_codes
WHERE country_code <> 0;

2)通过查找与区号开头匹配的国家/地区代码,更新国家/地区代码为0的所有行:

UPDATE country_codes AS country_codes_zero SET country_code = (
    SELECT country_code
    FROM country_codes_list
    WHERE country_codes_list.country_code = SUBSTRING(country_codes_zero.area_code, 1, LENGTH(country_codes_list.country_code))
) WHERE country_code = 0;

这可能是一个非常慢的查询,因为它使用了一个共同相关的子查询。但它应该一次性修复数据。

答案 3 :(得分:0)

假设您有一个名为“testdb”的数据库和一个名为“footable”的表,那么这样的东西应该可行。

$link = mysql_connect("localhost", "username", "password1234");
mysql_select_db("testdb", $link);

$result = mysql_query("UPDATE footable SET country_code="93" WHERE country LIKE Afghanistan%", $link);
$result = mysql_query("UPDATE footable SET country_code="355" WHERE country LIKE Albania%", $link);

mysql_close($link);

答案 4 :(得分:0)

您只能创建一个包含countries的表格,例如:

INSERT INTO countries (country_code,country)
SELECT country_code,country FROM country_codes WHERE country_code=0

然后您可以轻松更新表格

UPDATE country_codes cc, countries c
SET cc.country_code = c.country_code
WHERE LOCATE(c.country,cc.country)=1 AND cc.country_code=0

我没有对此进行测试,但我相信你可以明白这一点。