SQL:子查询中的参考列值和反之亦然

时间:2014-03-31 21:15:21

标签: mysql sql join subquery where

让我们说我正在处理类似这样的查询:

 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);

这意味着将我的用户表中的城市列表重复数据删除,以便在城市表中拥有共享相同城市名称的所有ID的最小城市ID。因此,重复数据删除。但是,我收到了这个错误:

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

我的用户表肯定有一个城市列,即

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)

所以我看到关于这个查询的两个有趣的事情,在子查询中引用用户表城市列值(u.city),并且在中间查询中使用来自city表的城市id,(select min( c1.id))。我该如何工作?

2 个答案:

答案 0 :(得分:2)

我认为使用显式join而不是嵌套查询更容易编写这样的查询:

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似乎也限制了嵌套在相关引用上的深度,尽管我还没有在任何地方发现这个限制。

答案 1 :(得分:0)

可能的解决方案: -

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