Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.02.2013, 09:34   #1
arvitaly
Пользователь
 
Аватар для arvitaly
 
Регистрация: 01.08.2010
Сообщений: 51
Вопрос Запрос из таблиц один ко многим

Такая задачка

Цитата:
table 1 (порядка 200к записей)
id name
Цитата:
table2 (соответственно, порядка 1млн записей)
id table1_id field2
Соответственно table1 и table2 соединяются по table1.id и table2.table1_id

Необходимо выбрать записи из первой таблицы по условию

Цитата:
(table2.id = 1 И table2.id = 3)
ИЛИ
(table2.id = 4 И table2.id = 5)
ИЛИ
(table2.id = 7 И table2.id = 9)
....
Помогите оптимизировать запрос :-) Пробовал subquery и join с group by
arvitaly вне форума Ответить с цитированием
Старый 22.02.2013, 09:58   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
table2.id = 1 И table2.id = 3
Это условие никогда не выполнится, впрочем как и другие два
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 22.02.2013, 10:22   #3
arvitaly
Пользователь
 
Аватар для arvitaly
 
Регистрация: 01.08.2010
Сообщений: 51
По умолчанию

Вот например

Код:
select * from table1 inner join table2 on (table2.table1_id = table1.id and ( table2.id = 1 or table2.id = 2 ) ) group by table1.id having count(*) = 2
Это для одного условия И, соответственно чтобы объединить их Union?

Код:
select * from table1 inner join table2 on (table2.table1_id = table1.id and ( table2.id = 1 or table2.id = 2 ) ) group by table1.id having count(*) = 2
union
select * from table1 inner join table2 on (table2.table1_id = table1.id and ( table2.id = 3 or table2.id = 4 ) ) group by table1.id having count(*) = 2

Пока чот не очень быстро пашет)

Второй вариант еще медленнее, что и логичнее, подзапросы

Код:
select * from table1 where

(
select count(*) from table2 where table1.id = table1_id and table2.id = 1)>0
and
select count(*) from table2 where table1.id = table1_id and table2.id = 2)>0
)
or

(
select count(*) from table2 where table1.id = table1_id and table2.id = 3)>0
and
select count(*) from table2 where table1.id = table1_id and table2.id = 4)>0
)
arvitaly вне форума Ответить с цитированием
Старый 22.02.2013, 11:27   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

1. table2.id = 1 or table2.id = 2 эквивалентно table2.id = 1 ИЛИ table2.id = 2. Это нормально, в отличии от написанного в #1
2. Лучше заменить на table2.id IN (1,2)
3. Судя по * и GROUP BY у вас MySQL. Тогда выполните EXPLAIN и посмотрите какие индексы задействованы. Скорее всего проблема в их отсутствии. По id в обеих таблицах они наверно есть, а вот по table1_id в table2 сомневаюсь
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Заполнение таблиц с со связью "Один ко многим" DenProx Microsoft Office Access 2 04.02.2011 10:24
Отношение один ко многим в Delphi reihtmonbern Помощь студентам 3 01.02.2011 04:39
вложенный запрос выборка по многим критериям Droid БД в Delphi 2 23.05.2010 19:31
Запрос из нескольких таблиц (отношение многие-ко-многим) Машуля SQL, базы данных 6 28.03.2010 09:51
связь один ко многим kate158 БД в Delphi 11 19.06.2009 09:13