Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Выбрать через join one to many where not in / 10 сообщений из 10, страница 1 из 1
25.02.2014, 20:44:47
    #38572232
maxtorchel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
есть 2 таблицы:
bill -> id,name
score ->id,bill_id,service

bill может иметь несколько score c разными service. Если нам надо выбрать список bill у которых есть score с service='delivery','collection' и 'carriage' мы это легко делаем так:
Код: sql
1.
select distinct(b.id) from bill b join score s on s.bill_id=b.id where b.service in ('delivery','collection','carriage')


Однако если нам надо выбрать bill у которых наоборот нет score с указанными service, то если сделать такой запрос наоборот:
Код: sql
1.
select distinct(b.id) from bill b join score s on s.bill_id=b.id where b.service NOT in ('delivery','collection','carriage')


то в него тоже могут попасть эти же bill так как помимо указанных service они действительно могут иметь и другие, и соответственно not in их выберет. Можно в not in засунуть первую выборку:
Код: sql
1.
select b.id from bill b where b.id NOT in (select distinct(b.id) from bill b join score s on s.bill_id=b.id where b.service in ('delivery','collection','carriage'))


однако такой запрос работает крайне медленно. Можно ли реализовать его за один запрос чтобы было быстрее.
Прбовал такое решение:
http://stackoverflow.com/questions/12630487/mysql-select-join-many-to-many-tables-plus-in-and-not-in
однако проблема в том что есть например такие service: 'delivery' и 'agent_delivery' и regexp их не различает.
...
Рейтинг: 0 / 0
25.02.2014, 20:53:05
    #38572238
maxtorchel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
например такая таблица:
bill score
1 bill1 1 1 delivery
2 bill2 2 1 carriage
3 bill3 3 2 delivery
4 2 delivery
5 3 collection

мне надо выбрать bill у которых нет score с service='delivery'. должно найти bill3
...
Рейтинг: 0 / 0
25.02.2014, 20:58:42
    #38572243
maxtorchel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
извиняюсь, вот так лучше:
bill
1bill12bill23bill3
score
11delivery21carriage32delivery42delivery53collection
...
Рейтинг: 0 / 0
25.02.2014, 21:04:48
    #38572247
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
так?
Код: sql
1.
2.
3.
4.
5.
6.
7.
select *
from bill b
where not exists(
  select 1 from score s
  where s.bill_id=b.id 
    and s.service in ('delivery','collection','carriage')
  );
...
Рейтинг: 0 / 0
25.02.2014, 21:24:58
    #38572262
maxtorchel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
да, спасибо, так работает но проблему скорости не решает, в реальной ситуации у меня мой запрос с вложенным селектом работает 19 секунд, а этот 17, что не сильно меня спасает.
...
Рейтинг: 0 / 0
25.02.2014, 23:51:11
    #38572319
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
индекс (bill_id,service) присутствует?
...
Рейтинг: 0 / 0
26.02.2014, 05:25:21
    #38572368
Выбрать через join one to many where not in
maxtorchelда, спасибо, так работает но проблему скорости не решает, в реальной ситуации у меня мой запрос с вложенным селектом работает 19 секунд, а этот 17, что не сильно меня спасает.попробуй подзапросы (not in | not exists) переписать через left semi join anti.
...
Рейтинг: 0 / 0
26.02.2014, 07:53:00
    #38572395
maxtorchel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
Cygapb-007индекс (bill_id,service) присутствует?
блин, я реально затупил и забыл добавить индекс к bill_id, спасибо, надо быть внимательнее.

Добрый Э - Эхпопробуй подзапросы (not in | not exists) переписать через left semi join anti.
Первый раз про такое слышу, в мануале и гугле по поводу таких запросов в мускуле ничего не написано. Где про это можно почитать?
...
Рейтинг: 0 / 0
26.02.2014, 07:54:00
    #38572397
tanglir
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
maxtorchel,

попробуйте поискать по "left join + is null"
...
Рейтинг: 0 / 0
26.02.2014, 07:59:27
    #38572398
maxtorchel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выбрать через join one to many where not in
Кстати, заметил что есть скрипты, которые делают выборку из бд (там может быть несколько запросов) медленно только первый раз, как и здесь было. Суть в кэше - это понятно. Правильно ли я понимаю что если есть такое что разница слишком большая, то значит надо искать чтолбец к которому нужно добавить индекс. Тоесть при правильно расставленных индексах разница не должна быть слишком большой.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Выбрать через join one to many where not in / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]