Javascript-форум (https://javascript.ru/forum/)
-   Серверные языки и технологии (https://javascript.ru/forum/server/)
-   -   SQL запрос. Как делать SELECT с условием SELECT (https://javascript.ru/forum/server/39734-sql-zapros-kak-delat-select-s-usloviem-select.html)

Duda.Ml1986@gmail.com 09.07.2013 21:51

SQL запрос. Как делать SELECT с условием SELECT
 
Приветствую.

Есть 3 таблицы.

books хранит данные о книге

user_books хранит данные id из book и id из users, то есть каждый пользователь из users может соответствовать одному или нескольким id из books

users хранит данные о пользователях.

Когда мне нужны книги пользователя из books (тоесть полные данные о книге) я вынужден :

1. Выбрать id пользователя из users т.к. единственная доступная инфа о пользователе: сессия с именем пользователя.

2. Выбрать из user_books все книги пользователям по id пользователя.

3. Выбрать из books данные по книгам по id книг полученные из предыдущего запроса (книг от 1...99 ).

Как можно сделать один такой запрос, например:

Код:

SELECT * FROM `books` WHERE `id`='
SELECT `id_books`FROM `user_books`WHERE `id_user`='
SELECT `id_user`FROM `users` WHERE `user_name`='$_SESSION[''Name']'' '

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

МОЖНО ЭТО СДЕЛАТЬ?

П.С. Можно получать id пользователя и в сессии, но тогда все равно остается запрос в запросе.

Буду благодарен за ссылку или пример.
Спасибо.

bes 09.07.2013 22:28

не вникал в то, что ты хочешь, но если хочешь получить конкретное значение при помощи выборки, то запрос (select) должен вернуть ровно одно значение, а сам он помещён в круглые скобки, если же идёт выборка из выборки, то не важно сколько значений вернёт выборка, но она должна быть помещена в круглые скобки

Duda.Ml1986@gmail.com 10.07.2013 00:22

Спасибо за ответы.

Получилось вот что:

SELECT * FROM 
  books b, user_books u, users s
  WHERE
  b.id = u.id_book 
  AND u.id_user = s.id AND
  s.id = 76


Только не совсем ясно как сделать иначе? Потому что:
1. Выбираем все книги которые имеют хозяина
2. из числа выбранных всех изеров которые имеют книги
3. потом оставляем только те книги которые соответсвуют id юзера.

Не слишком ли это затратно, если скажем обьем базы будет 50 мб?
Или всеже так делать норм?

ksa 10.07.2013 09:11

Цитата:

Сообщение от Duda.Ml1986@gmail.com
Когда мне нужны книги пользователя из books (тоесть полные данные о книге)

Как вариант...

select
	*
from
	user_books as ub
    left join books as b on b.id=ub.id_book 
where
	ub.id_user=76

ksa 10.07.2013 09:12

Цитата:

Сообщение от Duda.Ml1986@gmail.com (Сообщение 261431)
Получилось вот что:

SELECT * FROM 
  books b, user_books u, users s
  WHERE
  b.id = u.id_book 
  AND u.id_user = s.id AND
  s.id = 76

Делать декартов куб не продуктивно для решения твоей задачи...

Duda.Ml1986@gmail.com 10.07.2013 19:25

Спасибо.
Ответ гражданина Ksa в 2 раза быстрее чем мой вариант.

bes 10.07.2013 20:59

ksa, зачем внешнее соединение?
если соответствие не поставлено, то и книга не пользователя и пользователь не книги :)

--полные данные о книгах пользователя 76
SELECT * 
FROM books, user_books
WHERE books.id = user_books.id_book AND user_books.id_user = 76

и декартова произведения здесь нет, так как есть ограничивающие условия

ksa 11.07.2013 09:11

Цитата:

Сообщение от bes
и декартова произведения здесь нет

Оно там есть по определению... :D Просто к нему применяется условие.
Т.о. рассматриваются все (!) записи из books и все (!) записи из user_books. После чего к декартову квадрату применяется твое условие.

Соединение же работает несколько иначе...
Из user_books возьмутся только записи удовлетворяющие условию и к ним "присоединиться" запись из books согласно условию соединения.

Т.о. ожидается более быстрый ответ.

Цитата:

Сообщение от bes
если соответствие не поставлено, то и книга не пользователя и пользователь не книги

Это вообще не понял...

bes 11.07.2013 19:20

Цитата:

Сообщение от ksa
Оно там есть по определению... :D Просто к нему применяется условие.
Т.о. рассматриваются все (!) записи из books и все (!) записи из user_books. После чего к декартову квадрату применяется твое условие.

насколько мне известно, более-менее серьёзные субд (такие как от oracle) используют различные внутренние оптимизации для ускорения получения результатов запроса, поэтому описываемый тобой способ реализации запроса на данный момент удобен лишь для освоения sql ;)
предполагаю, что в приведённом мною запросе, это, как минимум, означает, что анализатор, не в последнюю очередь, выполнит второе условие, тем самым уже избавив от декартова произведения

Цитата:

Сообщение от ksa
Это вообще не понял...

я пояснил, что не вижу смысла оставлять лишние записи, которые ты потенциально оставил (если они есть), использовав внешнее соединение

ksa 12.07.2013 11:37

Цитата:

Сообщение от bes
не вижу смысла оставлять лишние записи, которые ты потенциально оставил

Автор использовал мой запрос - лишних записей там нет. :D

Цитата:

Сообщение от bes
описываемый тобой способ реализации запроса на данный момент удобен лишь для освоения sql

Это лишь твое мнение и не более того... :D


Часовой пояс GMT +3, время: 21:05.