Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mysql update all rows based on select from another table

Tags:

select

mysql

I have two tabels;

mysql> describe ipinfo.ip_group_country;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| ip_start     | bigint(20)  | NO   | PRI | NULL    |       |
| ip_cidr      | varchar(20) | NO   |     | NULL    |       |
| country_code | varchar(2)  | NO   | MUL | NULL    |       |
| country_name | varchar(64) | NO   |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+

mysql> describe logs.logs;
+----------------------+------------+------+-----+---------------------+----------------+
| Field                | Type       | Null | Key | Default             | Extra          |
+----------------------+------------+------+-----+---------------------+----------------+
| id                   | int(11)    | NO   | PRI | NULL                | auto_increment |
| ts                   | timestamp  | NO   |     | CURRENT_TIMESTAMP   |                |
| REMOTE_ADDR          | tinytext   | NO   |     | NULL                |                |
| COUNTRY_CODE         | char(2)    | NO   |     | NULL                |                |
+----------------------+------------+------+-----+---------------------+----------------+

I can select country code using ip address from first table:

mysql> SELECT country_code FROM ipinfo.`ip_group_country` where `ip_start` <= INET_ATON('74.125.45.100') order by ip_start desc limit 1;
+--------------+
| country_code |
+--------------+
| US           |
+--------------+

In logs.logs, I have all the REMOTE_ADDR (ip address) set, but all COUNTRY_CODE entries are empty. Now, I want to populate COUNTRY_CODE appropriately using the ipinfo table. How can I do this?

thanks!

like image 362
anon Avatar asked Jan 27 '11 13:01

anon


People also ask

How can I update data from one table to another table?

We can update the table using UPDATE statement in SQL. The update statement is always followed by the SET command. The SET command is used to specify which columns and values need to be updated in a table.

How do I update from a select in MySQL?

Method 2: UPDATE from SELECT: The MERGE statementUse a MERGE statement for updating data in the [Employee] table. It then references another table when the USING clause is applied. The WHEN MATCHED then specifies the merge JOIN (Inner Join) between the source and target table.


2 Answers

Try

UPDATE logs.logs
SET COUNTRY_CODE = (
    SELECT country_code
    FROM ipinfo.ip_group_country
    WHERE ipinfo.ip_start <= INET_ATON(logs.REMOTE_ADDR)
    LIMIT 1
)
WHERE COUNTRY_CODE IS NULL

If it fails saying the column types must match, you'll have to alter your logs.logs table so that the REMOTE_ADDR column is the same type (varchar(20)) as the ip_cidr table.

like image 66
Dean Rather Avatar answered Sep 22 '22 07:09

Dean Rather


In a single-table update you use update t1 set c1=x where y.

In a multi-table update you use update t1, t2 set t1.c1=t2.c2 where t1.c3=t2.c4

Here's the relevant documentation http://dev.mysql.com/doc/refman/5.0/en/update.html

What you're looking for is something along the lines of (editted) update logs.logs as l, ipinfo.ip_group_country as c set l.COUNTRY_CODE=c.country_code where c.ip_start <= INET_ATON(l.REMOTE_ADDR) order by c.ip_start asc

Edit: you're right, the max() in the original answer I provided could not work. The query above should, although it will likely be less efficient than something like the approach in the answer provided below.

like image 31
nicolaskruchten Avatar answered Sep 23 '22 07:09

nicolaskruchten