MySQL左连接(未知列)

时间:2012-09-15 23:54:19

标签: mysql sql join left-join

我的查询出现问题。

MySQL查询:

SELECT DISTINCT(`users`.`username`), `users`.`full_name`, `users`.`profile_picture_url`, 
`users`.`followed_by_count`, `users`.`follows_count`, `users`.`bio`, `users`.`id`
FROM `users`,`interests`
LEFT JOIN `blocked` 
ON `blocked`.`receiver_id` = `users`.`id`
AND `blocked`.`actor_id` = 100 
AND `blocked`.`blocked_reason` = 'Blocked'
WHERE `blocked`.`receiver_id` IS NULL 
AND `users`.`instagram_active` = 1 
AND `users`.`banned` = 0 
AND `interests`.`user_id` = `users`.`id` 
AND `interests`.`interest` = 'Food'
AND `interests`.`active` = 1 
AND `users`.`active` = 1
ORDER BY `users`.`last_login` DESC
LIMIT 0, 25

我得到的错误是:

  

1054 - 'on clause'

中的未知列'users.id'

当我选择它时,它是如何成为一个未知的列?

我很困惑......

用户:

CREATE TABLE `users` (    
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `instagram_id` int(11) NOT NULL,
 `username` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `bio` text COLLATE utf8_unicode_ci,
 `website` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `profile_picture_url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 `full_name` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
 `media_count` int(11) unsigned NOT NULL,
 `followed_by_count` int(11) unsigned NOT NULL,
 `follows_count` int(11) unsigned NOT NULL,
 `last_updated` datetime NOT NULL,
 `last_updated_instagram` datetime NOT NULL,
 `instagram_active` tinyint(1) DEFAULT NULL,
 `last_login` datetime NOT NULL,
 `inserted_on` datetime NOT NULL,
 `banned` tinyint(1) NOT NULL DEFAULT '0',
 `banned_reason` text COLLATE utf8_unicode_ci,
 `oauth_token` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
 `user_level` tinyint(4) NOT NULL,
 `shown_to_others` tinyint(1) NOT NULL DEFAULT '1',
 `credits_offered` tinyint(1) unsigned NOT NULL DEFAULT '2',
 `active` tinyint(1) NOT NULL DEFAULT '1',
 `email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 `registered_ip` varchar(17) COLLATE utf8_unicode_ci DEFAULT NULL,
 `credits` int(11) NOT NULL,
 `email_notifications` tinyint(1) NOT NULL DEFAULT '1',
 `todays_followers` int(11) NOT NULL DEFAULT '0',
 `todays_followers_hour` int(11) NOT NULL,
 `total_followers` int(11) NOT NULL,
 `credits_yesterday` int(11) NOT NULL,
 `email_is_verified` tinyint(1) NOT NULL DEFAULT '0',
 `email_announcements` tinyint(1) NOT NULL DEFAULT '1',
 `email_credits` tinyint(1) NOT NULL DEFAULT '1',
 `verification_code` varchar(25) COLLATE utf8_unicode_ci DEFAULT NULL,
 `country_id` bigint(20) unsigned DEFAULT NULL,
 `browser_info_id` bigint(20) unsigned DEFAULT NULL,
 `featured_user` tinyint(1) NOT NULL DEFAULT '0',
 `emailed_credits` tinyint(1) NOT NULL DEFAULT '0',
 UNIQUE KEY `id` (`id`),
 UNIQUE KEY `instagram_id` (`instagram_id`),
 KEY `country_id` (`country_id`),
 KEY `browser_info_id` (`browser_info_id`),
 KEY `username` (`username`,`instagram_active`,`banned`),
 CONSTRAINT `users_ibfk_1` FOREIGN KEY (`country_id`) REFERENCES `countries` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
 CONSTRAINT `users_ibfk_2` FOREIGN KEY (`browser_info_id`) REFERENCES `browser_info` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1279 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

兴趣:

CREATE TABLE `interests` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `user_id` bigint(20) unsigned NOT NULL,
 `interest` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
 `inserted_dt` datetime NOT NULL,
 `active` tinyint(1) NOT NULL DEFAULT '1',
 UNIQUE KEY `id` (`id`),
 KEY `user_id` (`user_id`),
 KEY `interest` (`interest`),
 CONSTRAINT `interests_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4161 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

阻止:

CREATE TABLE `blocked` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `actor_id` bigint(20) unsigned NOT NULL,
 `receiver_id` bigint(20) unsigned DEFAULT NULL,
 `blocked_reason` enum('Skipped','Blocked') COLLATE utf8_unicode_ci NOT NULL,
 `inserted_dt` datetime NOT NULL,
 `active` tinyint(1) NOT NULL DEFAULT '1',
 `browser_info_id` bigint(20) unsigned DEFAULT NULL,
 UNIQUE KEY `id` (`id`),
 KEY `actor_id` (`actor_id`,`receiver_id`),
 KEY `receiver_id` (`receiver_id`),
 KEY `browser_info_id` (`browser_info_id`),
 CONSTRAINT `blocked_ibfk_1` FOREIGN KEY (`actor_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `blocked_ibfk_2` FOREIGN KEY (`receiver_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `blocked_ibfk_3` FOREIGN KEY (`browser_info_id`) REFERENCES `browser_info` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=5700 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

3 个答案:

答案 0 :(得分:17)

正如JOIN Syntax所述:

  

加入MySQL 5.0.12中的处理更改

     

[ deletia ]

     
      
  • 以前,逗号运算符(,)和JOIN都具有相同的优先级,因此连接表达式t1, t2 JOIN t3被解释为((t1, t2) JOIN t3)。现在JOIN具有更高的优先级,因此表达式被解释为(t1, (t2 JOIN t3))。此更改会影响使用ON子句的语句,因为该子句只能引用连接操作数中的列,并且优先级的更改会更改这些操作数的解释。

         

    示例:

    CREATE TABLE t1 (i1 INT, j1 INT);
    CREATE TABLE t2 (i2 INT, j2 INT);
    CREATE TABLE t3 (i3 INT, j3 INT);
    INSERT INTO t1 VALUES(1,1);
    INSERT INTO t2 VALUES(1,1);
    INSERT INTO t3 VALUES(1,1);
    SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);
         

    以前,SELECT是合法的,因为t1,t2隐式分组为(t1,t2)。现在JOIN优先,因此ON子句的操作数为t2t3。由于t1.i1不是任一操作数中的列,因此结果为Unknown column 't1.i1' in 'on clause'错误。要允许处理连接,请使用括号将前两个表显式分组,以便ON子句的操作数为(t1,t2)t3

    SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
         

    或者,避免使用逗号运算符并改为使用JOIN

    SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);
         

    此更改也适用于将逗号运算符与INNER JOINCROSS JOINLEFT JOINRIGHT JOIN混合在一起的语句,所有这些语句现在都具有比逗号更高的优先级操作

  •   

答案 1 :(得分:1)

您的from子句未在表之间加入。如果要分析查询,请尝试:

from `users` cross join
     `interests` LEFT JOIN
     `blocked`
     on . . .

或者,更好的是,正确地表达联接:

from `users` join
     `interests` 
     on `interests`.`user_id` = `users`.`id` LEFT JOIN
     `blocked`
     on . . . 

我的建议是:不要在FROM语句中使用“,”。这意味着CROSS JOIN,如果你错过WHERE子句中的条件,这是一个非常昂贵的操作。逗号很容易错过。您可以删除逗号,第二个表成为第一个的别名 - 一个非常不同的含义。另外,不要在WHERE子句中放置连接条件。这就是ON子句正在做的事情。

但是,我很惊讶MySQL在这种情况下会产生错误,大概是因为你们之间没有明确的表连接。

答案 2 :(得分:0)

MySQL说的确如此,因为在LEFT JOIN时间不知道ID列(它是在表USERS加入之前完成的)。试试这个:

SELECT DISTINCT( `users`.`username` ),
               `users`.`full_name`,
               `users`.`profile_picture_url`,
               `users`.`followed_by_count`,
               `users`.`follows_count`,
               `users`.`bio`,
               `users`.`id`
FROM   `users`
       JOIN `interests`
         ON `interests`.`user_id` = `users`.`id`
       LEFT JOIN `blocked`
              ON `blocked`.`receiver_id` = `users`.`id`
                 AND `blocked`.`actor_id` = 100
                 AND `blocked`.`blocked_reason` = 'Blocked'
WHERE  `blocked`.`receiver_id` IS NULL
       AND `users`.`instagram_active` = 1
       AND `users`.`banned` = 0
       AND `interests`.`interest` = 'Food'
       AND `interests`.`active` = 1
       AND `users`.`active` = 1
ORDER  BY `users`.`last_login` DESC
LIMIT  0, 25