MySQL 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-неизвестные пользователи столбца.id ' in 'on clause'

как это неизвестный столбец, когда я его выбираю?

Я очень смущен...

потребители:

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 ответов


как описано в разделе JOIN синтаксис:

Присоединяйтесь к обработке изменений в 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 as (t1,t2). Теперь JOIN имеет приоритет, поэтому операнды для ON статьи t2 и t3. Потому что 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 JOIN, CROSS JOIN, LEFT JOIN и RIGHT JOIN, все из которых теперь есть более высокий приоритет, чем оператор "запятая".


ваше предложение 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. Это означает перекрестное соединение, что является очень дорогой операцией, если вы пропустите условие в предложении WHERE. Запятую легко пропустить. Вы можете удалить запятую, и вторая таблица станет псевдонимом для первой - совсем другой значение. Кроме того, не ставьте условия join в предложение WHERE. Это то, что делает предложение ON.

Я, однако, удивлен, что MySQL генерирует ошибку в этом случае, предположительно, потому что у вас нет явного соединения между таблицами.


Это правда, что говорит MySQL, потому что столбец ID не известен во время левого соединения (это делается до того, как пользователи таблицы присоединяются). Попробуйте это:

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