Текущий архив: 2005.12.11;
Скачать: CL | DM;
ВнизДва курсора и один НД Найти похожие ветки
← →
msguns © (2005-10-27 12:15) [0]В скале не орел, но вот мне было сказано, что нельзя параллельно работать с двумя курсорами, а только по очереди.
Я чувствую, что вешают мне нагло лапшу, но как собака, сказать ничего не могу.
Суть такова:
Есть две таблицы, в каждой из которых имеется дата и №. Надо на выходе ХП получить такую вещь
Табл.1
---------
Дата №
1.01 2
1.01 5
6.01 8
10.01 14
15.01 24
Табл.2
---------
Дата №
1.01 25
4.01 26
6.01 28
11.01 29
14.01 30
20.01 33
На выходе
------------
Дата П № П Дата Н № Н
1.01 2 1.01 25
1.01 5
4.01 26
6.01 8 6.01 28
10.01 14
11.01 29
14.01 30
15.01 24
20.01 33
Для чего сканируются параллельно оба курсора и данные обоих таблиц "собираются" в одну "строчку", которая затем добавляется в выходной НД.
← →
Ega23 © (2005-10-27 12:31) [1]а может воспользоваться Full Outer Join? :о)
← →
msguns © (2005-10-27 12:57) [2]>Ega23 © (27.10.05 12:31) [1]
>а может воспользоваться Full Outer Join? :о)
Дело в том, что я для наглядности сильно упростил алгоритм, на самом деле там все несколько сложнее ;) А фул джоин (первое, что мне пришло в голову) вернул такую кашу Э8:0
← →
Ega23 © (2005-10-27 13:03) [3]Но в любом случае - параллельно работать с двумя курсорами нельзя.
Вот представь себе это в delphi
← →
Nikolay M. © (2005-10-27 13:07) [4]1) WITH CUBE/ROLLUP не подойдет?
2) А двумя лефт джойнами, связывая по дате?SELECT
FROM A
LEFT JOIN B
UNION
SELECT
FROM B
LEFT JOIN A
а UNION убьет дубли в тех случаях, когда даты присутствуют в обеих таблицах.
← →
msguns © (2005-10-27 14:26) [5]>Ega23 © (27.10.05 13:03) [3]
>Но в любом случае - параллельно работать с двумя курсорами нельзя.
Ну что, ж, наставит пацанва мне шелбанов ;) Мдя, тяжело быть дураком ;((
>Вот представь себе это в delphi
??? Два датасета и в циклах перебираются. Новые ключи добавляются в третий датасет, уже существующие в вых.датасете просто корректятся (вносятся соотв. пары полей)
>Nikolay M. © (27.10.05 13:07) [4]
Я все-таки придавил их авторитетом и заставил все сделать одним запросом. Правда запрос получился монстерным, с 4 - мя уровнями вложенности (Select from select), 2 из которых убирают "мусор" после фулджойнов..
Но ведь по сабжу я был неправ ;(((
← →
Ega23 © (2005-10-27 14:43) [6]
> ?? Два датасета и в циклах перебираются. Новые ключи добавляются
> в третий датасет, уже существующие в вых.датасете просто
> корректятся (вносятся соотв. пары полей)
>
Но это же не параллельно. Сначала один цикл, потом - другой.
Или может я что-то не так понимаю? Что ты имеешь ввиду под "параллельностью"?
← →
Nikolay M. © (2005-10-27 15:29) [7]
> Я все-таки придавил их авторитетом и заставил все сделать
> одним запросом.
Это неправильно. Когда поймут, что можно было сделать проще и быстрее, давить уже будет нечем.
> наставит пацанва мне шелбанов ;)
И правильно сделают.
← →
msguns © (2005-10-27 15:42) [8]>Или может я что-то не так понимаю? Что ты имеешь ввиду под "параллельностью"?
Блин, нет под рукой удобоваримого примера..
Мне надо, просматривая и сравнивая последовательно 2 разных НД, выводить в третий результирующие записи.
← →
Ega23 © (2005-10-27 15:50) [9]
> Мне надо, просматривая и сравнивая последовательно 2 разных
> НД, выводить в третий результирующие записи.
>
Т.е. одна итерация в первом цикле, потом итерация во втором, потом снова в первом, снова во втором и т.д.?
AFAIK, так нельзя.
← →
msguns © (2005-10-27 15:51) [10]>Nikolay M. © (27.10.05 15:29) [7]
>Это неправильно. Когда поймут, что можно было сделать проще и быстрее, давить уже будет нечем.
Вот это их произведение (фрагмент):--протоколы и отгрузка распределенная по видам документов
select sp.docid, sp.docdate, sp.docnum, sp.td
into #sp
from
(
select d.dgid as docid, d.dgdt as docdate,"" as docnum, 0 as td
from dgv d
left join dgvfakt df on d.dgid=df.dgid
where d.dgid=@dgid
and df.dgfspnum=@spnum
and df.zid=@zid
and df.vpid=@vpid
union
select p.ptid as docid, p.ptdate as docdate, p.ptnum as docnum,0 as td
from dgvprot p, dgvfaktprot dfp
where p.ptid=dfp.ptid
and p.dgid=@dgid
and dfp.ptfspnum=@spnum
and dfp.zid=@zid
and dfp.vpid=@vpid
union
select do.dcoid as docid, do.dcodt as docdate, do.dconum as docnum, 1 as td
from docfaktout dfo, docout do, dgv d
where do.dgid=@dgid
and do.dgid=d.dgid
and dfo.dcoid=do.dcoid
and dfo.spnum=@spnum
and dfo.vpid=@vpid
and dfo.prid in (select prid from drgp where zid=@zid)
group by do.dcoid, do.dcodt, do.dconum
)sp
-----------------------------------------------------------------
select s.docdate,s.docnum,s.td,p.ptdate,p.ptnum,p.ptkol,null as otdate, null as otnum, null as otkol
from #sp s
----- протоколы
join
(
select d.dgid as ptid, d.dgdt as ptdate, "" as ptnum, df.dgfcenarn as ptcena,
df.dgfkolpln as ptkol, null as ptkurs, null as ptsumma, (df.dgfcenarn * df.dgfkolpln) as ptsummac
from dgv d
left join dgvfakt df on d.dgid=df.dgid
where d.dgid=@dgid
and df.dgfspnum=@spnum
and df.zid=@zid
and df.vpid=@vpid
union
select p.ptid, p.ptdate, p.ptnum, dfp.ptfcena as ptcena,
dfp.ptfkol as ptkol, null as ptkurs, null as ptsumma, (dfp.ptfcena*dfp.ptfkol) as ptsummac
from dgvprot p, dgvfaktprot dfp
where p.ptid=dfp.ptid
and p.dgid=@dgid
and dfp.ptfspnum=@spnum
and dfp.zid=@zid
and dfp.vpid=@vpid
)p on s.docid=p.ptid and s.docdate=p.ptdate and s.docnum=p.ptnum
where s.td=0
UNION
--s.docdate,s.docnum,p.ptdate,p.ptnum,p.ptkol
select s1.docdate,s1.docnum,s1.td,null,null,null,ot.otdate, ot.otnum, ot.otkol
from #sp s1
-----отгрузка
join
(
select do.dcoid as otid, do.dcodt as otdate, do.dconum as otnum, sum(dfo.dcfokol) as otkol, do.dcokurs as otkurs,
sum(dfo.dcfocenauch*dcfokol) as otsumuch, sum(dfo.dcfokol*dcfocenarc) as otsumrc,
sum(dfo.dcfocenarc*dcfokol*do.dcokurs) as otsumr
from docfaktout dfo, docout do, dgv d
where do.dgid=@dgid
and do.dgid=d.dgid
and dfo.dcoid=do.dcoid
and dfo.spnum=@spnum
and dfo.vpid=@vpid
and dfo.prid in (select prid from drgp where zid=@zid)
group by do.dcoid, do.dcodt, do.dconum,do.dcokurs
)ot on s1.docid=ot.otid and s1.docdate=ot.otdate and s1.docnum=ot.otnum
where s1.td=1
order by 1,3,2
Смысл этого небоскреба в том, что сначала выбираются "головки" документов и отгрузок (ID,Дата,№), а затем к ним надо "пристегнуть" хвост из аналит.данных (в разные поля, составляющие 2 группы полей: по договору (протоколам) и отгрузкам.
Так вот, нафгига "хвосты" из трех таблиц "склеивать" юнионом, для чего, собственно, и строится временная табла #sp (чтобы не рисовать "головочный" запрос в каждой юнион-секции), если можно все эту хрень запуздырить в "одну грядку", используя (((Left Join..) Left Join..) Left Join..
Или я неправ ?
← →
Nikolay M. © (2005-10-27 16:07) [11]
> Смысл этого небоскреба
Имхо, это подход ораклиста - наваять стоэтажный запрос, который оракл успешно схавает.
В мсскульной практике, как правило, для разработчика и субд удобнее делить такие запросы на несколько промежуточных запросов и временными таблицами.
Страницы: 1 вся ветка
Текущий архив: 2005.12.11;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.04 c