Как написать левое соединение с предложением where, ограничивающим левую часть в нескольких таблицах? - PullRequest
2 голосов
/ 24 ноября 2011

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

Если я просто сделаю левое соединение, e. г.

select *
from table_A A
left join table_B B on A.id=B.id

все хорошо. Я могу достаточно безопасно добавить предложение where, например

where A.id>5

Проблема возникает, когда я пытаюсь разместить несколько таблиц с левой стороны, например

select *
from table_A, table_C
left join table_B on A.id=B.id
where table_A.id=table_C.id

Внезапно A.id больше не является признанным столбцом. Я попытался изменить его, чтобы выбрать A.id в качестве foo, а затем выполнить команду на foo = B.id, но foo также не распознается. (Неизвестный столбец «бла» в «предложении»)

Несмотря на то, что существует множество ссылок, в которых объясняется, как сделать предложение объединения, а в некоторых примерах даже используется простое предложение where, я не могу найти ни одного, который бы объединял предложение join, предложение where и несколько таблиц в левая сторона.

Для справки по вопросу:

Мой оригинальный запрос был:

select SQL_CALC_FOUND_ROWS tutor_user.username
    , tutor_user.userid
    , tutor_tutor.rate
    , tutor_user.username 
from tutor_user
    , tutor_attends
    , tutor_tutors_in
    , tutor_subject
    , tutor_tutor 
where tutor_user.userid=tutor_attends.userid 
    and tutor_attends.schoolid=80 
    and tutor_tutors_in.userid=tutor_user.userid 
    and tutor_tutors_in.subjectid=tutor_subject.subjectID 
    and tutor_subject.name='Aerospace Studies' 
    and tutor_tutor.userid=tutor_user.userid //ERROR
LIMIT 0, 15

К сожалению, нет гарантии, что информация tutor_tutor будет существовать для каждого пользователя - незначительный недостаток, который сохраняется из-за неправильных решений на ранних этапах цикла разработки веб-сайта / базы данных. Итак, простое решение - превратить его в объединение.

Проблема в том, что я не могу найти хороших учебных пособий, объясняющих, как объединять предложения с предложениями where. Мое лучшее усилие заключается в следующем:

select SQL_CALC_FOUND_ROWS tutor_user.username
    , tutor_user.userid
    , tutor_tutor.rate
    , tutor_user.username 
from tutor_user
    , tutor_attends
    , tutor_tutors_in
    , tutor_subject
LEFT JOIN tutor_tutor
    on tutor_user.userid=tutor_tutor.userid
where tutor_user.userid=tutor_attends.userid 
    and tutor_attends.schoolid=80 
    and tutor_tutors_in.userid=tutor_user.userid 
    and tutor_tutors_in.subjectid=tutor_subject.subjectID 
    and tutor_subject.name='Aerospace Studies' 
    LIMIT 0, 15

Ответы [ 4 ]

5 голосов
/ 24 ноября 2011

В идеале не следует смешивать синтаксис отложенного соединения (select ... from a,b,c) с более конкретным select ... from a join B ... join c .... И выполнение select * также может быть проблематичным, особенно если вы не собираетесь использовать все поля или должны ссылаться на поля по имени, а не по позиции.

Таким образом, ваш запрос должен быть:

SELECT A.field, A.otherfield, B.field, B.otherfield, C.yetanotherfield
FROM table_A AS A
JOIN table_B as B on A.id = B.a_id
JOIN table_C as C on B.id = C.b_id
WHERE ...
3 голосов
/ 24 ноября 2011

ки.Много вещей ...

select * from table_A, table_C left join table_B on A.id = B.id где table_A.id = table_C.id Внезапно A.idбольше не распознанный столбец.Я попытался изменить его, чтобы выбрать A.id в качестве foo, а затем выполнить команду на foo = B.id, но foo также не распознается.(Неизвестный столбец «bla» в «предложении»)

Эта проблема со столбцом не распознана: нет таблицы или псевдонима с именем A. Вам нужно поместить псевдоним перед именем таблицы:

select *
from table_A A, table_C
left join table_B on A.id=B.id
where table_A.id=table_C.id

Но почему вы используете соединение с запятой (,)?
Лучше использовать оператор соединения.Это должно быть примерно так:

select * /* any collmn you want */
from tutor_user u
  left join tutor_attends a ON a.userid = u.userid
  left join tutor_tutors_in t ON t.userid = u.userid  
  left join tutor_subject s ON s.subjectid = t.subjectid
  LEFT JOIN tutor_tutor tt on u.userid = tt.userid 

where tutor_attends.schoolid=80 
and tutor_subject.name='Aerospace Studies'

Посмотрите на псевдоним.
Также вы можете попробовать документ: http://dev.mysql.com/doc/refman/5.0/en/select.html

3 голосов
/ 24 ноября 2011

Вы можете поместить несколько предложений в JOIN, например,

SELECT * 
FROM table_a A
    LEFT OUTER JOIN table_b B
        ON A.col1 = B.col1 
             AND A.col2 = B.col2
             AND B.col3 > 5

. Вы можете записать критерии в предложении where, но это устаревшая запись.Однако, если вы все же хотите использовать условие объединения в WHERE, тогда добавьте OR для обработки NULL, в противном случае оно перестает быть LEFT JOIN

, например,

SELECT * 
FROM table_a A
    LEFT OUTER JOIN table_b B
        ON A.col1 = B.col1 
             AND A.col2 = B.col2
WHERE (B.col3 > 5 OR B.col3 IS NULL)
2 голосов
/ 24 ноября 2011

Наверное, нужно что-то вроде этого:

select A.*, B.field1, C.field3 from A
    left join B on A.id=B.id
    left join C on A.id=C.id
    where C.field5 = 'foo'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...