简体   繁体   中英

SQL: Reference Column Value in Subquery and Vice Versa

Lets say I am working on a query that looks something like this:

 update user as u 
   set u.city = (
    select min(c1.id) 
       from (
         select c1.id 
           from city c1 
          where c1.name = (
            select c2.name 
              from city c2 where c2.id = u.city)) as duplicates);

Which is meant to dedupe the city list in my user table to have the smallest city id in the city table of all id's which share the same city name. Hence the deduping. However, I get this error:

ERROR 1054 (42S22): Unknown column 'u.city' in 'where clause'

My user table definitely does have a city column, ie

mysql> describe user;
+----------------------------+--------------+------+-----+---------+----------------+
| Field                      | Type         | Null | Key | Default | Extra          |
+----------------------------+--------------+------+-----+---------+----------------+
| id                         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| first_name                 | varchar(64)  | YES  |     | NULL    |                |
| last_name                  | varchar(64)  | YES  |     | NULL    |                |
...
| city                       | bigint(20)   | YES  | MUL | NULL    |                |
...
+----------------------------+--------------+------+-----+---------+----------------+
36 rows in set (0.00 sec)

So I see two interestng things about this query, the user table city column value (u.city) is referred to in the subquery, and the city id from the city table is used in the middle query, (select min(c1.id)). How do I make this work?

I think such a query is more easily written using explicit join s rather than nested queries:

update user u join
       city c
       on u.city = c.city join
       (select name, min(id) as minid
        from city
        group by name
       ) cmin
       on cmin.name = c.name
    set u.city = cmin.minid;

MySQL also seems to have a limit on how deep a nesting can go on correlated references, although I haven't found this limit documented anywhere.

Possible solution:-

UPDATE user 
INNER JOIN
(             
    SELECT u.city, MIN(c1.id) AS min_city
    FROM user u
    INNER JOIN city c2 ON c2.id = u.city
    INNER JOIN city.c1 ON c1.name = c2.name
    GROUP BY u.city
) sub1
ON u.city = sub1.city
SET u.city = sub1.min_city

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM