Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.5 MB
Время: 0.054 c
14-1132355247
Eraser
2005-11-19 02:07
2005.12.11
Знатокам алгоритмов сжатия, в частности, ZLib


14-1132659255
gn
2005-11-22 14:34
2005.12.11
перевод с английского


8-1120939291
line
2005-07-10 00:01
2005.12.11
Вопрос о режимах смешивания изображений.


3-1130411409
diwww
2005-10-27 15:10
2005.12.11
Получить позицию первой выводимой записи в DBGrid-е


4-1127738848
NikNet
2005-09-26 16:47
2005.12.11
Как сделать мою форму позади всех?