Многоэлементный идентификатор ... не удалось связать [37000] - запрос SQL 2005 - PullRequest
0 голосов
/ 09 ноября 2011

Я понимаю, что это довольно распространенное явление, но я не смог исправить это до сих пор после прохождения подобных проблем, перечисленных на этом сайте и в других местах.

В любом случае, у меня на форуме есть приложение на основе PHP, которое позволяет пользователям выставлять друг другу очки репутации, я уверен, что вы все знаете, как работают эти простые настройки, поэтому я не буду останавливаться на этом. Проблема в том, что этот фрагмент кода изначально был написан для MySQL, и я полагаю, что хотя 95% его было преобразовано в MS SQL и работает в нем, остаются некоторые запросы, которые, похоже, не годятся для SQL 2005 из-за небольшого несоответствия синтаксиса в соединениях и т. д. Это застряло у меня. Пример запроса следующий:

SELECT TOP 25 p.post_id, p.post_subject, p.forum_id, u.username, u.user_id, 
 u.user_colour, r.rep_id, r.rep_from, r.rep_to, r.rep_time, r.rep_post_id, 
 r.rep_point, r.rep_comment, r.enable_urls, r.rep_ip_address, r.username 
FROM forum_reputations r, forum_users u 
LEFT JOIN forum_posts p ON (r.rep_post_id = p.post_id) 
WHERE r.rep_to = 61
ORDER BY r.rep_id DESC

Данные следующие:

**Forum_Posts**:
post_id (int, PK)
post_subject (varchar)
forum_id (int)

**Forum_users**:
username (varchar)
user_id (int, PK)
user_colour (varchar)

**Forum_reputations**:
rep_id (int, PK)
rep_from (int) 
rep_to (int)
rep_time (int)
rep_post_id (int)
rep_point (int)
rep_comment (text)
enable_urls (int) 
rep_ip_address (varchar) 
username (varchar)

При выполнении запроса SQL Server выдает следующую знакомую ошибку:

[Microsoft][ODBC SQL Server Driver][SQL Server]The multi-part identifier "r.rep_post_id" could not be bound. [37000]

Я изо всех сил пытаюсь понять, почему это происходит. Очевидно, намекнуло, что rep_post_id имеет проблему, но я проверил синтаксис запроса и имена столбцов / таблиц, и все они правильные, я даже попытался заключить любые объекты, которые звучали удаленно, как зарезервированные слова SQL, в квадратные скобки (то есть u. [Имя пользователя ], т. [имя пользователя] и т. д.), но это не имеет значения. Интересно, что если я изменю предложение FROM таким образом, что Forum_users u будет перед Forum_users r, ошибка больше не будет возникать, и данные будут возвращены, но это не очень полезно, поскольку оно разрушает левое соединение и вытягивает верхние 25 из таблицы пользователей, игнорируя, есть ли у них какие-либо связанные записи в таблице репутации.

Предполагается, что выходные данные состоят из таблицы, в которой перечислено следующее для каждой записи повторения для пользователя (r.rep_to):

Количество набранных очков репутации (r.rep_point)

Пользователь, который дал очки (r.rep_from, u.user_id, u.username)

Дата начисления очков (r.rep_time)

Комментарий, введенный пользователем, дающий очки репутации (r.rep_comment)

Сообщение на форуме, которому был отдан ответ (r.rep_post_id, p.post_id, p.post_subject)

Если у кого-нибудь возникнут мысли о том, что происходит не так или как это можно реструктурировать, я был бы очень признателен за информацию об этом. Я понимаю, что это, вероятно, что-то очень элементарное, но я действительно не вижу здесь дерево для деревьев!

Спасибо

Ответы [ 2 ]

1 голос
/ 09 ноября 2011

try

SELECT TOP 25 p.post_id, p.post_subject, p.forum_id, u.username, u.user_id, 
 u.user_colour, r.rep_id, r.rep_from, r.rep_to, r.rep_time, r.rep_post_id, 
 r.rep_point, r.rep_comment, r.enable_urls, r.rep_ip_address, r.username 
FROM forum_reputations r
JOIN forum_users u 
ON u.user_id = r.rep_from
LEFT JOIN forum_posts p ON r.rep_post_id = p.post_id 
WHERE r.rep_to = 61
ORDER BY r.rep_id DESC

Это не имеет непосредственного отношения к вашему вопросу, но условие соединения между forum_users и forum_reputation отсутствует в вашем запросе - это будет производить декартово произведение.Я добавил соединение выше, но немного догадываюсь, находится ли оно в правом столбце.

0 голосов
/ 09 ноября 2011

Вы не можете комбинировать неявные и явные объединения и ожидать, что они будут работать правильно. Вы должны сделать все объединения явными, что вы должны делать в любом случае, поскольку неявные объединения являются антипаттерном SQL.

Это явная версия того, что у вас есть:

SELECT TOP 25 p.post_id, p.post_subject, p.forum_id, u.username, u.user_id,
u.user_colour, r.rep_id, r.rep_from, r.rep_to, r.rep_time, r.rep_post_id,  
r.rep_point, r.rep_comment, r.enable_urls, r.rep_ip_address, r.username  
FROM forum_reputations r
CROSS JOIN forum_users u  
LEFT JOIN forum_posts p ON r.rep_post_id = p.post_id  
WHERE r.rep_to = 61 
ORDER BY r.rep_id DESC 

Однако я подозреваю, что это НЕ то, что вы хотите. Я думаю, что @EdHarper имеет правильную идею.

...