Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сложный sql запрос / 9 сообщений из 9, страница 1 из 1
04.11.2013, 06:51:09
    #38451576
Илья В.
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
Теория: в таблице "а" некие объекты, в таблицах "b" и "c" содержат свойства объектов. Нужно выбрать объекты у которых есть набор определенных свойств одновременно. Объектов 200 000, свойств в одного 30 шт.

CREATE TABLE `a` (
`id` int(10)
);
INSERT INTO `a` (`id`) VALUES
(1),
(2);

CREATE TABLE `b` (
`a_id` int(10),
`num` int(10)
);
INSERT INTO `b` (`a_id`, `num`) VALUES
(1, 3),
(1, 4),
(2, 3);

CREATE TABLE `c` (
`a_id` int(10),
`num` int(10)
);
INSERT INTO `c` (`a_id`, `num`) VALUES
(1, 6),
(1, 7),
(2, 6);

Таблицы "b" и "c" имеют связь с таблицей "а" по полю "a_id".

1. Цель выбрать id из таблицы "а", где в таблице "b" есть num=3 и num=4. Т.е. должно выбраться только id=1.

2. Цель выбрать id из таблицы "а", где в таблице "b" есть num=3 и в таблице "с" num=6 и num=7. Т.е. должно выбраться id=1.

Подсказали решение, но имхо очень тяжелое для железа (30 свойств = 30 JOIN):

SELECT * FROM a
JOIN (SELECT * FROM b WHERE b.num = 3) AS b3
JOIN (SELECT * FROM b WHERE b.num = 4) AS b4
WHERE b3.a_id = b4.a_id AND a.id = b3.a_id
...
Рейтинг: 0 / 0
04.11.2013, 08:11:43
    #38451586
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
Илья В.,

Несколько подзапросов, вводимых через Exist и объединенных по И.
...
Рейтинг: 0 / 0
04.11.2013, 12:41:23
    #38451698
qwerty112
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
Илья В.Подсказали решение, но имхо очень тяжелое для железа (30 свойств = 30 JOIN):

MasterZivИлья В.,

Несколько подзапросов, вводимых через Exist и объединенных по И.
тогда будет 30 Exist , вместо 30 JOIN, что тоже, наверняка, "не фонтан" ...

ТС,

в общем случае, для 2-х таблиц (твой в.2) так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select `a`.`id`
from `a`
inner join
  (select `a_id` from b where `num` in (3)
  group by `a_id` having count(*)=1) t1
on a.id=t1.a_id
inner join
  (select `a_id` from c where `num` in (6,7)
  group by `a_id` having count(*)=2) t2
on a.id=t2.a_id


или так
Код: sql
1.
2.
3.
4.
5.
6.
7.
select `a`.`id`
from `a`
inner join b on a.id=b.a_id
inner join c on a.id=c.a_id
where b.`num` in (3) and c.`num` in (6,7)
group by `a`.`id`
having count(distinct b.num)=1 and count(distinct c.num)=2


(имхо, 1-ый способ - лучше)
...
Рейтинг: 0 / 0
04.11.2013, 17:03:20
    #38452036
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
qwerty112,

огда будет 30 Exist , вместо 30 JOIN, что тоже, наверняка, "не фонтан"

плевать, хоть 200 join. Все равно.
...
Рейтинг: 0 / 0
04.11.2013, 17:37:19
    #38452080
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
MasterZivплевать, хоть 200 join. Все равно.200 нельзя, в лимит упретесь.
...
Рейтинг: 0 / 0
04.11.2013, 19:05:59
    #38452172
transpose
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
qwerty112
Код: sql
1.
2.
3.
4.
5.
6.
7.
select `a`.`id`
from `a`
inner join b on a.id=b.a_id
inner join c on a.id=c.a_id
where b.`num` in (3) and c.`num` in (6,7)
group by `a`.`id`
having count(distinct b.num)=1 and count(distinct c.num)=2


(имхо, 1-ый способ - лучше)

Если правила все одинаковые по форме, то можно еще добавить таблицу (таблицы) типа b_conditions

Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE `b_conditions` (
`id` int(10),
`b_num` int(10)
);
INSERT INTO `b_conditions` (`id`, `b_num`) VALUES
(1, 6),
(2, 7);



и потом так

Код: plsql
1.
2.
3.
4.
5.
6.
7.
select a.id, min (case when b_conditions.id is null then 0 else 1 end) as b_join_indicator --не должно попадаться невыполненных условий
from a
inner join b on a.id=b.a_id
inner join c on a.id=c.a_id
left outer join b_conditions on b.num=b_conditions.b_num 
group by a.id
having b_join_indicator = 1


то-же самое и для других таблиц, c,d,e etc.
...
Рейтинг: 0 / 0
05.11.2013, 10:35:25
    #38452620
Илья В.
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
Спасибо.
...
Рейтинг: 0 / 0
05.11.2013, 15:29:39
    #38453175
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
transposeqwerty112
Код: sql
1.
2.
3.
4.
5.
6.
7.
select `a`.`id`
from `a`
inner join b on a.id=b.a_id
inner join c on a.id=c.a_id
where b.`num` in (3) and c.`num` in (6,7)
group by `a`.`id`
having count(distinct b.num)=1 and count(distinct c.num)=2


(имхо, 1-ый способ - лучше)

Если правила все одинаковые по форме, то можно еще добавить таблицу (таблицы) типа b_conditions

Код: plsql
1.
2.
3.
4.
5.
6.
7.
CREATE TABLE `b_conditions` (
`id` int(10),
`b_num` int(10)
);
INSERT INTO `b_conditions` (`id`, `b_num`) VALUES
(1, 6),
(2, 7);



и потом так

Код: plsql
1.
2.
3.
4.
5.
6.
7.
select a.id, min (case when b_conditions.id is null then 0 else 1 end) as b_join_indicator --не должно попадаться невыполненных условий
from a
inner join b on a.id=b.a_id
inner join c on a.id=c.a_id
left outer join b_conditions on b.num=b_conditions.b_num 
group by a.id
having b_join_indicator = 1


то-же самое и для других таблиц, c,d,e etc.


Т.е. ты реально считаешь, что эти запросы проще ?
...
Рейтинг: 0 / 0
08.11.2013, 17:11:12
    #38458231
transpose
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный sql запрос
MasterZiv,

На мой взгляд так проще поддерживать, отлаживать и развивать.
1) логика отделена от данных. Не придется править код, если поменяются данные.
2) если нужно автоматизировать - может быть проще тиражировать на новые таблицы, так как идея остается, созаются только новые таблицы.
3) возможно будет легче оптимизировать запрос, так как данные и условия уже лежат в базе а не в коде.
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сложный sql запрос / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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