![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите с SQL запросом
jack128 © (2006-04-11 14:47:00)День добрый. Такой вопросик возник
есть таблицы
materials (id, caption...)
generalizations (id, caption, period_id)
generalization_material_links (material_id, generalization_id)
для каждого материала на каждый период может быть задано одно обобщение (generalization) (но не обязательно).
Задача - выбрать все материалы + дополнительной колонкой id обобщения на заданный период.
например
materials
id caption
0 битон марки А
1 битон марки Б
2 битон марки В
3 битон марки Д
4 битон марки Е
generalizations
id caption period
0 обощение 1 1
1 обощение 2 2
2 обощение 3 1
generalization_material_links
material_id generalization_id
1 0
2 1
3 0
3 1
4 2
SQL.ParamByName('period_id').AsInteger := 0;
результат должен быть следующим
material_id material_caption generalization_id
0 битон марки А null
1 битон марки Б 0
2 битон марки С null
3 битон марки Д 0
4 битон марки Е 2
jack128 (2006-04-12 22:51:00) [1]Johnmen © (12.04.06 10:49) [9]
Кстати, запрос в [7], который "работает вроде правельно", наиболее правильное идеологически решение
Может быть. Но работает он в 8 медленнее. 2,3 сек против 0,3 - для твоего запроса..
Johnmen (2006-04-12 10:49:00) [2]>jack128 © (12.04.06 10:40) [8]
Кстати, запрос в [7], который "работает вроде правельно", наиболее правильное идеологически решение.
А то, что я привёл, просто его аналог, записанный в "другом порядке" :)
jack128 (2006-04-12 10:40:00) [3]Johnmen © (12.04.06 10:33) [6]
Ндя.. Как всегда.. Я тут извращаюсь, страшные запросы пишу, а всё решается простеньким подзапросом...
jack128 (2006-04-12 10:36:00) [4]SergP © (12.04.06 2:21) [5]
нет, FB такое не хавает.
Вчера ребята меня надоумили( Ega23, paul_k - спасибо) и вот что получилось:
select m.id as material_id, m.caption, gml.generalization_id
from generalization_material_links gml
join generalizations g on g.id = gml.generalization_id and g.period_id = :period_id
right join materials m on m.id = gml.material_id
работает вроде правельно.
похожий вариант у меня был:
select m.id as material_id, m.caption, gml.generalization_id
from materials m
left join generalization_material_links gml on gml.material_id = m.id
join generalizations g on g.id = gml.generalization_id and g.period_id = :period_id
проблема как видно была в порядке объединений. Мне нужно было сначала сделать inner join, а потом уже left. А реально в этом запросе сначала выполняется left, а потом к результату применяется inner . в результате отсекаются материалы, для которых не задано обобщение в текущем периоде..
Отсюда вопрос: замена left join на right - это стандартный способ изменнения порядка объединений???
Johnmen (2006-04-12 10:33:00) [5]
SELECT
M.id,
M.caption,
(SELECT L.generalization_id FROM generalization_material_links L
JOIN generalizations G ON G.id=L.generalization_id
WHERE (L.material_id=M.id) AND (G.period=1))
FROM materials M
SergP (2006-04-12 02:21:00) [6]Хм... Только что заметил... Топикстартер без комплексов однако.
Вспомнилась ветка одного из обычных посетителей, который сильно обижался на действия модераторов...
SergP. (2006-04-12 02:04:00) [7]наверное так:
SELECT a.id, a.caption, d.generalization_id
FROM materials a
LEFT JOIN
(select c.*
from generalization_material_links c, generalizations b
where c.generalization_id=b.id and b.period=:period_id) d
ON a.id=d.material_id;
Не знаю как в IB/FB, но акцесс такое хавает...
jack128 (2006-04-11 23:47:00) [8]Johnmen © (11.04.06 15:50) [2]
SQL.ParamByName('period_id').AsInteger := 0;
но такого периода нет. Откуда же получим данные?
Ох. Сглючил. Естественно имелось в виду SQL.ParamByName('period_id').AsInteger := 1;
Desdechado © (11.04.06 15:46) [1]
СУБД какая?
IB/FB
Desdechado © (11.04.06 15:46) [1]
не понял также, нужно выбрать только одно обобщение? какое тогда?
да, только одно. ТО, которое соответствует материалу в текущем периоде.такое обобщение может быть только одно(или же null - если такого обобщения нет вообще)
Johnmen (2006-04-11 15:50:00) [9]Тут несколько непонятных (ошибочных?) моментов.
1. марки В и С
2 битон марки В
и
2 битон марки С
2.
SQL.ParamByName('period_id').AsInteger := 0;
но такого периода нет. Откуда же получим данные?
Desdechado (2006-04-11 15:46:00) [10]СУБД какая?
не понял также, нужно выбрать только одно обобщение? какое тогда?
и почему для периода 0, если он в таблице отсутствует, вдруг результат с обобщениями появился?
а так видится select ... left outer join (select ... )