За последние 24 часа нас посетили 17800 программистов и 1625 роботов. Сейчас ищут 1866 программистов ...

Выборка из нескольких таблиц

Тема в разделе "PHP и базы данных", создана пользователем alnik-75, 13 дек 2017.

  1. alnik-75

    alnik-75 Новичок

    С нами с:
    13 дек 2017
    Сообщения:
    10
    Симпатии:
    0
    Уважаемые форумчане! помогите с запросом. Есть три таблицы:

    - a
    id_man man
    1 Вася
    2 Петя
    3 Коля

    - в
    id_book book
    1 Война и Мир
    2 Идиот
    3 Ревизор
    4 Преступление и наказание

    - c (таблица связей)
    id_man id_book
    1 3
    1 4
    2 1
    2 3
    3 2
    3 3
    3 4

    Вопрос: как, имея имя (например, Петя), выбрать все книги, которых у него нет?

    как выбрать все книги, которые у него есть - пожалуйста, а в этом случае, почему то туплю

    Заранее спасибо за помощь
     
  2. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    JOIN. Показывай как пробуешь.
     
  3. alnik-75

    alnik-75 Новичок

    С нами с:
    13 дек 2017
    Сообщения:
    10
    Симпатии:
    0
    PHP:
    1. 'SELECT b.book
    2.                     FROM a, b, c
    3.                     WHERE b.id_book != c.id_book AND c.id_man = a.id_man AND a.man= "' . $man . '"'
    Конечно же это не правильно. JOIN не использовал. , если честно
     
  4. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Чот я подумал... Тут можно и без джойна но с подзапросом: выбрать все книги, где айди книги не в (выбрать все связи.айди-книги из связи, пользователи где связь.пользователь равно пользователь.айди и пользователь имя равно ДОЛЛАР-ИМЯ)
    Подзапрос можно не умножением а джойном.
    Всё вместе можно без подзапроса а с джойном.
    Но тебе пока кажется проще будет с подзапросом.
     
  5. alnik-75

    alnik-75 Новичок

    С нами с:
    13 дек 2017
    Сообщения:
    10
    Симпатии:
    0
    PHP:
    1. 'SELECT b.book
    2.  FROM b
    3.  WHERE b.id_book NOT IN (SELECT c.id_book
    4. FROM a, c
    5. WHERE c.id_man = a.id_man AND a.man = "' . $man. '")'
    Спасибо. все работает.

    Вопрос, хочется сразу же научиться делать оптимальные (правильные запросы). Подскажите или направьте, как будет лучше? я так понимаю подзапрос - это дополнительное обращение к БД и, соответственно, лишняя нагрузка. join я так понимаю позволит сделать выборку в рамках одного запроса. Пока что не очень силен в них
     
  6. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    не совсем так. Вот когда ты стреляешь себе в ногу выбирая все данные в пых и обрабатывая на стороне пыха, в цикле делая запросы за недостающими связями - тогда ты нагружаешь базу. А когда ты делаешь комплексные запросы - собственный оптимизатор СУБД старается построить результирующую таблицу наиболее оптимальным планом. Можешь сделать EXPLAIN и посмотреть что думает СУБД по твой запрос со вложенным запросом. Там же кстати и увидишь используются ли у тебя индексы.
     
  7. Taktreba

    Taktreba Активный пользователь

    С нами с:
    11 янв 2017
    Сообщения:
    543
    Симпатии:
    132
    как это понимать? можешь подробней? это какой то процесс оптимизации?
     
  8. alnik-75

    alnik-75 Новичок

    С нами с:
    13 дек 2017
    Сообщения:
    10
    Симпатии:
    0
    сделал я EXPLAIN в phpmyadmin . еще в крайней степени слабоват и поэтому ничего в полученной таблице не увидел к сожалению)))
     
  9. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    не понял твоего вопроса. У тебя все запросы к данным работают с кортежами. Запросы обновления и удаления "начинаются" примерно так же как и запросы выборки этих же кортежей, поэтому ты можешь сделать селект-запрос чтоб увидеть какие объекты в результирующей таблице (в случае выборки - вернутся, в случае обновления - обновятся, при удалении - удалятся. Ваш Кэп.). А если дописать ключевое слово explain перед этим селект-запросом то можно увидеть в каком порядке и с использованием каких ключей субд собирала результирующую таблицу, использовался ли горячий кэш или пришлось перечитывать данные с диска, использовались ли временные таблицы, и тд. Полезная штука, помогающая ещё и правильно разрабатывать структуру бд.
     
    Taktreba нравится это.
  10. alnik-75

    alnik-75 Новичок

    С нами с:
    13 дек 2017
    Сообщения:
    10
    Симпатии:
    0
    если Вас не затруднит, могли бы Вы помочь подвязать к данному запросу JOIN?
     
  11. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @alnik-75 а что тебя в текущем виде не устраивает? Работает же.
     
  12. alnik-75

    alnik-75 Новичок

    С нами с:
    13 дек 2017
    Сообщения:
    10
    Симпатии:
    0
    хотелось бы посмотреть, какой из запросов будет работать быстрее
     
  13. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    А текущий медленно работает?
     
  14. alnik-75

    alnik-75 Новичок

    С нами с:
    13 дек 2017
    Сообщения:
    10
    Симпатии:
    0
    нет, но просто хотелось подучиться и посмотреть заодно, что быстрее работает
     
  15. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    Ты сам-то материал по джоинам изучил? Попробовал? Мне понравилось как ты вчера не включил халявщика, не стал просить готовый код, а просто транслировал моё сообщение в лексемы языка структурированных запросов. Да, моя заслуга в этом тоже есть - я дал почти готовый запрос, просто русскими словами. Давай ты с джойнами пару-тройку вариантов пришлёшь чтоб я не просто так давал тебе готовый код.
     
  16. alnik-75

    alnik-75 Новичок

    С нами с:
    13 дек 2017
    Сообщения:
    10
    Симпатии:
    0
    ок. попробую чуть позже и отпишусь тогда
     
  17. AlexProg

    AlexProg Активный пользователь

    С нами с:
    13 май 2014
    Сообщения:
    320
    Симпатии:
    7
    PHP:
    1. SELECT db_a.user,
    2.                        db_a.date_reg,
    3.               FROM db_a, db_b
    4.               WHERE db_a.id = db_b.id
    Ну или JOIN (особенно когда из трех таблиц)
     
  18. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @webog задачу внимательно прочитай.
     
  19. glorsh66

    glorsh66 Активный пользователь

    С нами с:
    9 июл 2017
    Сообщения:
    247
    Симпатии:
    4
    Кстати что быстрее join или вложенные запросы?
     
  20. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    @glorsh66 напрямую зависит от архитектуры бд и конфигурации сервера. В разных случаях могут быть разные результаты.
     
    denis01 нравится это.
  21. glorsh66

    glorsh66 Активный пользователь

    С нами с:
    9 июл 2017
    Сообщения:
    247
    Симпатии:
    4
    Спрошу тогда еще один вопрос - он близко по теме - как тестировать скорость выполнения запросов?
    Например я хочу протестировать время выполнения (и нагрузку) трех подходов
    1) отдельные запросы по очереди
    2) join
    3) вложенные запросы

    Какой инструментарий использовать что бы получить наибоее точные резульаты?
    (ну понятно что лучше всего сделать миллион записей для теста).
     
  22. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.893
    Симпатии:
    965
    explain подскажет тебе некоторые полезные данные.
    тестировать синтетически можно просто сделать функцию тестирования вокруг которой замерить время её выполнения. и в цикле её несколько раз вызывать для более точного среднего значения.