Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Оптимизировать SQL-запрос

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Составить запрос с помощью JOIN, вместо вложенных запросов
Deonis
Отправлено: 21 Мая, 2014 - 17:24:01
Post Id



Посетитель


Покинул форум
Сообщений всего: 298
Дата рег-ции: Нояб. 2009  


Помог: 14 раз(а)




Всем привет! Для упрощения, взял абстрактную задачу, аналогичную существующей.
1. Есть таблица с заказами, в которой каждый заказ привязан к менеджеру
2. Вторая таблица - содержит записи ID-заказа и ID-менеджера, которые должны игнорироваться.
Нужно: Выбрать из талицы заказов те записи, которые есть у определенного менеджера, но которых нет в таблице с игнорируемыми заказами у этого же менеджера.
Пример закинул в песочницу (url с хешем "режется" на форуме, посему ссылка TinyURL), где есть два менеджера и для первого (с ID = 1), есть два заказа, которые не должны учитываться при выборке.
На данный момент, есть запрос, который исправно работает, но хотелось бы оптимизировать:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT * FROM `orders` WHERE `ord_id` NOT IN (
  2.   SELECT `o_id` FROM `ignore_orders` WHERE `m_id` = ?
  3. ) AND `manager_id` = ?
Где в плейсхолдер (?) подставляется ID менеджера.
Толи я не выспался, толи что-то у меня сегодня с руками, но через JOIN переделать запрос не получается. Буду признателен, если подтолкнете в нужном направлении.

(Отредактировано автором: 21 Мая, 2014 - 17:25:01)

 
 Top
EuGen Администратор
Отправлено: 21 Мая, 2014 - 17:31:34
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Deonis пишет:
На данный момент, есть запрос, который исправно работает,

Если речь о MySQL, то, в случае, если подзапрос не является зависимым, начиная с версии 5.6 (возможно, даже 5.5) СУБД автоматически преобразует его в соответствующий JOIN.

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

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT
  2.   `orders`.*
  3. FROM `orders`
  4.   LEFT JOIN `ignore_orders`
  5.     ON `orders`.`ord_id`=`ignore_orders`.`o_id`
  6. WHERE
  7.   `ignore_orders` .`id` IS NULL
  8.   AND
  9.   `orders`.`manager_id` = ?


Условие из подзапроса я убрал, предполагая, что m_id там - это то же самое manager_id во внешнем условии (то есть, так как мы делаем JOIN, это условие будет излишне). Поле id для таблицы ignore_orders "взято с потолка", это просто должно быть что-то, являющееся первичным ключом (чтобы можно было гарантировать, что наличие NULL для LEFT JOIN в этом поле означает отсутствие соответствующей записи)


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Deonis
Отправлено: 21 Мая, 2014 - 17:37:21
Post Id



Посетитель


Покинул форум
Сообщений всего: 298
Дата рег-ции: Нояб. 2009  


Помог: 14 раз(а)




EuGen пишет:
то есть, так как мы делаем JOIN, это условие будет излишне
Спасибо! Вот то, что я упустил из виду. А я дурень его лепил вторым условием в JOIN
EuGen пишет:
начиная с версии 5.6 (возможно, даже 5.5) СУБД автоматически преобразует его в соответствующий JOIN
За это отдельное спасибо, т.к. не знал Улыбка

(Отредактировано автором: 21 Мая, 2014 - 17:39:28)

 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB