Необъяснимый внутренний запрос - PullRequest
0 голосов
/ 20 января 2009

У меня есть вложенный запрос SQL, который показывает результаты, которые я не могу понять. Запрос объединяет таблицы PARTNER и USER через таблицу PARTNER_USER. Партнер - это, по сути, совокупность пользователей, и цель этого запроса - выяснить, когда 20-й пользователь зарегистрировался у партнера с ID 34:

select p.partner_id id,
       u.created_on launch_date
from   user u join partner_user pu
using (user_id) join partner p
using (partner_id)
where  p.partner_id = 34
and    u.user_id     =
       (select  nu.user_id
       from     user nu
       join     partner_user npu using (user_id)
       join     partner np using (partner_id)
       where    np.partner_id = 34
       order by nu.created_on limit 19, 1)

Однако, если я изменю 2-ю последнюю строчку на

       where    np.partner_id = p.partner_id

Запрос не выполняется с сообщением об ошибке «Подзапрос возвращает более 1 строки». Почему работает первый запрос, а не второй? Они выглядят эквивалентно мне.

Спасибо, Don

Ответы [ 4 ]

3 голосов
/ 20 января 2009

JPunyon прав. Сначала необходимо выполнить тот или иной запрос, а затем обрезать его результаты по факту.

Если вы посмотрите на запросы как написанные, внешний запрос должен знать результат внутреннего запроса, чтобы применить его условие where. Однако при указании

where    np.partner_id = p.partner_id

во внутреннем запросе, то вы пытаетесь заставить внутренний запрос узнать результат внешнего запроса, чтобы применить его предложение where. Это круговая зависимость.

Как человек, вы можете прочитать запрос и сказать, что в данном конкретном случае вы запрашиваете одно конкретное значение в предложении where во внешнем запросе и просите использовать это же значение в внутренний запрос, поэтому кажется, что база данных должна увидеть это и использовать то же буквальное значение из внешнего запроса.

На самом деле внутренний запрос просто выполняется первым, не зная возможных значений p.partner_id, отсюда и ошибка «несколько строк».

1 голос
/ 20 января 2009

Если вы используете оператор = для сравнения с результатами подзапроса, ваш подзапрос может вернуть только одну строку. если вы хотите проверить все строки, возвращаемые подзапросом, вы должны использовать оператор IN.

AND u.User_Id IN ( SELECT .... )
0 голосов
/ 31 июля 2010

@ Джейсон Пуньон mysql поддерживает конструкцию USING.

0 голосов
/ 20 января 2009

Когда вы меняете предложение where в подзапросе, вы открываете шлюзы. Предложение where в основном запросе не ограничивает подзапрос. Таким образом, вы получаете более 1 результата.

РЕДАКТИРОВАТЬ: Что это за база данных? Я раньше не сталкивался с конструкцией "using" ...

...