如果存在子查询,则未知已加入列

时间:2015-01-19 10:38:39

标签: mysql

我有两个表:queriesdays,按原样创建:

CREATE TEMPORARY TABLE `days` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `day` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8

CREATE TABLE `queries` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `from_lat` decimal(10,6) NOT NULL,
  `from_lon` decimal(10,6) NOT NULL,
  `to_lat` decimal(10,6) NOT NULL,
  `to_lon` decimal(10,6) NOT NULL,
  `city` varchar(64) NOT NULL DEFAULT '',
  `duration` float NOT NULL COMMENT 'query execution duration',
  `query_datetime` datetime NOT NULL,
  `execution_datetime` datetime NOT NULL,
  `result` varchar(50) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  KEY `from_lat` (`from_lat`),
  KEY `from_lon` (`from_lon`),
  KEY `to_lat` (`to_lat`),
  KEY `to_lon` (`to_lon`),
  KEY `execution_datetime` (`execution_datetime`),
  KEY `city` (`city`),
  KEY `result` (`result`),
  KEY `execution_datetime_2` (`execution_datetime`,`city`)
) ENGINE=InnoDB AUTO_INCREMENT=27338 DEFAULT CHARSET=utf8

这里是days的内容:

+----+------------+
| id | day        |
+----+------------+
|  1 | 2014-12-21 |
|  2 | 2014-12-22 |
|  3 | 2014-12-23 |
|  4 | 2014-12-24 |
|  5 | 2014-12-25 |
|  6 | 2014-12-26 |
|  7 | 2014-12-27 |
|  8 | 2014-12-28 |
|  9 | 2014-12-29 |
| 10 | 2014-12-30 |
| 11 | 2014-12-31 |
| 12 | 2015-01-01 |
| 13 | 2015-01-02 |
| 14 | 2015-01-03 |
| 15 | 2015-01-04 |
| 16 | 2015-01-05 |
| 17 | 2015-01-06 |
| 18 | 2015-01-07 |
| 19 | 2015-01-08 |
| 20 | 2015-01-09 |
| 21 | 2015-01-10 |
| 22 | 2015-01-11 |
| 23 | 2015-01-12 |
| 24 | 2015-01-13 |
| 25 | 2015-01-14 |
| 26 | 2015-01-15 |
| 27 | 2015-01-16 |
| 28 | 2015-01-17 |
| 29 | 2015-01-18 |
| 30 | 2015-01-19 |
+----+------------+

现在,如果我从加入queries表的days表中选择数据,那就是我所拥有的(截断为10行)

mysql> select d.day, q.id
    -> from days d
    -> left join queries q on date(q.execution_datetime) = d.day
    -> limit 10;
+------------+-------+
| day        | id    |
+------------+-------+
| 2014-12-21 | 15343 |
| 2014-12-21 | 15344 |
| 2014-12-21 | 15345 |
| 2014-12-21 | 15346 |
| 2014-12-21 | 15347 |
| 2014-12-21 | 15348 |
| 2014-12-21 | 15349 |
| 2014-12-21 | 15350 |
| 2014-12-21 | 15351 |
| 2014-12-21 | 15352 |
+------------+-------+
10 rows in set (0.06 sec)

现在,如果我加入一个简单的子查询:

select city from queries group by city

然后出现错误:

mysql> select d.day, q.id
    -> from days d,
    -> (select city from queries group by city) c
    -> left join queries q on date(q.execution_datetime) = d.day
    -> limit 10;
ERROR 1054 (42S22): Unknown column 'd.day' in 'on clause'

如果我加入此子查询,它可以工作:

mysql> select d.day, c.city
    -> from days d
    -> left join (select city from queries group by city) c on 1
    -> left join queries q on date(q.execution_datetime) = d.day and q.city = c.city
    -> limit 10;
+------------+----------+
| day        | city     |
+------------+----------+
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
| 2014-12-21 | adelaide |
+------------+----------+
10 rows in set (0.00 sec)

为什么?

1 个答案:

答案 0 :(得分:2)

您的问题是您将逗号语法与显式连接语法混合。查询无法确定别名d的来源,因为它位于逗号之前,而on子句位于join子句之后。

另一方面,当您使用上一个示例中的显式连接语法时,别名d可以从连接语句中正确地确定为属于表days

MySQL documentation有这样说:

  

但是,逗号运算符的优先级小于INNER JOIN,CROSS JOIN,LEFT JOIN等。如果在存在连接条件时将逗号连接与其他连接类型混合,则可能会出现'on子句'中未知列'col_name'形式的错误。