Update specific records of MySQL table

前端 未结 5 1339
没有蜡笔的小新
没有蜡笔的小新 2021-01-13 00:41

I am dealing with phone system and have to work with multiple service vendors. For one vendor I have a MySQL table country_codes like this -

--         


        
相关标签:
5条回答
  • 2021-01-13 01:14

    If you need to do the fix the data ONLY once, you can try this approach:

    0) Backup your data, or better, run the query on copy of the data.

    1) Creates a table that contains non-zero country codes. We need separate table because it says in MySQL manual that:

    Currently, you cannot update a table and select from the same table in a subquery.

    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) Update all rows where country code is 0 by finding the country code that matches the beginning of the area code:

    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;
    

    This could be a very slow query because it uses a co-related sub-query. But it should fix the data in one go.

    0 讨论(0)
  • 2021-01-13 01:25

    Something like this should work, assuming you have a database called "testdb", and a table called "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);
    
    0 讨论(0)
  • 2021-01-13 01:26

    You can create a table with countries only, i.e.:

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

    Then you can easily update your table

    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
    

    I haven't tested this, but I believe you can get the point.

    0 讨论(0)
  • 2021-01-13 01:30
    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, '%')
    

    I've added cc.country like concat(t.country, '%') to condition to be more specific but it assumes that each cellular network name starts with its country name - so if it's not true omit it.

    Added after @Sachyn comment:

    Test code used on SQLZOO works fine, it is for testing only, it's not an update query:

    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, '%')
    
    0 讨论(0)
  • 2021-01-13 01:36

    Try this query -

    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)
    
    0 讨论(0)
提交回复
热议问题