Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.30;
Скачать: CL | DM;

Вниз

Помогите с SQL запросом   Найти похожие ветки 

 
jack128 ©   (2006-04-11 14:47) [0]

День добрый.  Такой вопросик возник

есть таблицы

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  


 
Desdechado ©   (2006-04-11 15:46) [1]

СУБД какая?
не понял также, нужно выбрать только одно обобщение? какое тогда?
и почему для периода 0, если он в таблице отсутствует, вдруг результат с обобщениями появился?

а так видится select ... left outer join (select ... )


 
Johnmen ©   (2006-04-11 15:50) [2]

Тут несколько непонятных (ошибочных?) моментов.

1. марки В и С
2  битон марки В
и
2            битон марки С

2.
SQL.ParamByName("period_id").AsInteger := 0;
но такого периода нет. Откуда же получим данные?


 
jack128 ©   (2006-04-11 23:47) [3]

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 - если такого обобщения нет вообще)


 
SergP.   (2006-04-12 02:04) [4]

наверное так:


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, но акцесс такое хавает...


 
SergP ©   (2006-04-12 02:21) [5]

Хм... Только что заметил... Топикстартер без комплексов однако.

Вспомнилась ветка одного из обычных посетителей, который сильно обижался на действия модераторов...


 
Johnmen ©   (2006-04-12 10:33) [6]


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


 
jack128 ©   (2006-04-12 10:36) [7]

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 - это стандартный способ изменнения порядка объединений???


 
jack128 ©   (2006-04-12 10:40) [8]

Johnmen ©   (12.04.06 10:33) [6]

Ндя.. Как всегда..  Я тут извращаюсь, страшные запросы пишу, а всё решается простеньким подзапросом...


 
Johnmen ©   (2006-04-12 10:49) [9]

>jack128 ©   (12.04.06 10:40) [8]

Кстати, запрос в [7], который "работает вроде правельно", наиболее правильное идеологически решение.
А то, что я привёл, просто его аналог, записанный в "другом порядке" :)


 
jack128 ©   (2006-04-12 22:51) [10]

Johnmen ©   (12.04.06 10:49) [9]
Кстати, запрос в [7], который "работает вроде правельно", наиболее правильное идеологически решение

Может быть.  Но работает он в 8 медленнее.  2,3 сек против 0,3 - для твоего запроса..



Страницы: 1 вся ветка

Текущий архив: 2006.04.30;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.028 c
2-1144828707
Дмитрий_177
2006-04-12 11:58
2006.04.30
Класс для хранения шрифта и его настроек в файле


2-1144838409
Alex_C
2006-04-12 14:40
2006.04.30
Как отслеживать, запущено ли приложение?


2-1145013235
Дарья
2006-04-14 15:13
2006.04.30
stringlist


2-1145001367
Dust
2006-04-14 11:56
2006.04.30
Рекурсивный обход папок,,, или не рекурсивный...


15-1144400144
McSimm
2006-04-07 12:55
2006.04.30
Кстати, может кому-то интересно все-таки решить кто не знает.