我有两个表:queries
和days
,按原样创建:
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)
为什么?
答案 0 :(得分:2)
您的问题是您将逗号语法与显式连接语法混合。查询无法确定别名d
的来源,因为它位于逗号之前,而on
子句位于join
子句之后。
另一方面,当您使用上一个示例中的显式连接语法时,别名d
可以从连接语句中正确地确定为属于表days
。
MySQL documentation有这样说:
但是,逗号运算符的优先级小于INNER JOIN,CROSS JOIN,LEFT JOIN等。如果在存在连接条件时将逗号连接与其他连接类型混合,则可能会出现'on子句'中未知列'col_name'形式的错误。