Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2005.12.11;
Скачать: [xml.tar.bz2];

Вниз

Два курсора и один НД   Найти похожие ветки 

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.035 c
1-1131810203
Nikos
2005-11-12 18:43
2005.12.11
Ошибка возведения числа в квадрат


14-1132296979
MBo
2005-11-18 09:56
2005.12.11
Пятничные задачки с участием несравненного Васи Пупкина ;)


14-1132302901
Rentgen
2005-11-18 11:35
2005.12.11
Д.Р. на работе


14-1132393898
x.pro
2005-11-19 12:51
2005.12.11
Что означает LOL?


2-1132670570
ABS
2005-11-22 17:42
2005.12.11
Запуск exe





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский