Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / помогите с запросом / 19 сообщений из 19, страница 1 из 1
21.08.2006, 16:51
    #33932825
angro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
есть 2 таблицы

schet62_01 и schet62_02

с такой структурой

Kontragent | dogovor | summa

надо сделать отчёт в котором будут эти счета колонками, и сгруппировать по контрагенту и договору

делаю так

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
select 
   kontragent,
   dogovor,
   sum(summa62_01),
   sum(summa62_02)
from (select
           kontragent,
           dogovor,
           summa as summa62_01,
            0  as summa62_02
       from 
          schet62_01

       union all 

       select
          kontragent,
          dogovor,
           0  as summa62_01,
          summa as summa62_02
       from 
          schet62_01)

group by    kontragent, dogovor

вроде работает, но теперь надо отфильровать по тем контрагентам у которых остатки и на 62.01 и на 62.02 собственно вопрос как? если сделать having то тогда будет фильтроваться и по договорам, а надо только по контрагентам.
...
Рейтинг: 0 / 0
22.08.2006, 12:40
    #33934350
angro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
наверное плохо объяснил, ещё раз попытаюсь

в результате моего запроса получается вот такая таблица

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
контрагенты | договора | сумма1 | сумма2
___________________________________________
контрагент1 | договор1 |   10   |    0
-------------------------------------------
контрагент1 | договор2 |   10   |    0
-------------------------------------------
контрагент2 | договор1 |   0    |    10
-------------------------------------------
контрагент3 | договор1 |   10   |    0
-------------------------------------------
контрагент3 | договор2 |   0    |    11
-------------------------------------------
контрагент3 | договор3 |   0    |    12
-------------------------------------------

надо так отфильтровать запрос так чтобы остался только контрагент3, потому что у него есть и сумма1 и сумма2
...
Рейтинг: 0 / 0
22.08.2006, 15:45
    #33935177
Andrew Sagulin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Работать будет, но медленно.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
select 
   kontragent,
   dogovor,
   sum(summa62_01),
   sum(summa62_02)
from (select
           kontragent,
           dogovor,
           summa as summa62_01,
            0  as summa62_02
       from 
          schet62_01

       union all 

       select
          kontragent,
          dogovor,
           0  as summa62_01,
          summa as summa62_02
       from 
          schet62_02)
     as s

group by kontragent, dogovor
having (select sum(summa) from schet62_01 where kontragent = s.kontragent) >  0  and 
  (select sum(summa) from schet62_02 where kontragent = s.kontragent) >  0 
...
Рейтинг: 0 / 0
28.08.2006, 06:08
    #33945778
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Andrew SagulinРаботать будет, но медленно.
Код: plaintext
1.
2.
3.
4.
5.
select 
   ...
from ...
group by ...
having ...
Ну, в целом, Вы в правильном направлении идёте, товарищ! Вот только немного ещё подумать и будет вполне нормальный и очень неплохо работающий вариант.
Сам додумаешься или подсказать ;) ?
...
Рейтинг: 0 / 0
28.08.2006, 08:09
    #33945820
Andrew Sagulin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Владимор КоневНу, в целом, Вы в правильном направлении идёте, товарищ! Вот только немного ещё подумать и будет вполне нормальный и очень неплохо работающий вариант.
Сам додумаешься или подсказать ;) ?

Не додумаюсь, подскажи. :) Я перепробовал несколько вариантов и везде получается больше двух вложенных подзапросов, что есть не гуд и медленно.
Кстати, у меня складывается (возможно обманчивое) впечатление, что здесь что-то не то с нормализацией.
...
Рейтинг: 0 / 0
28.08.2006, 08:29
    #33945831
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Andrew SagulinНе додумаюсь, подскажи. :) Во-первых, нужно отказаться от использования группировки; во-вторых, проверку наличия остатков нужно снести во фразы WHERE соответствующих секций UNION, а саму проверку сделать посредством [NOT] EXISTS. Надеюсь мысль понятна?
Это НЕ ПОЗВОЛИТ уйти от подзапросов, но позволит ЗНАЧИТЕЛЬНО облегчить жизнь серверу.
...
Рейтинг: 0 / 0
28.08.2006, 08:33
    #33945834
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Ой, про группировку, возможно, поторопился.
Все зависит от того, сколько строк с остатками по каждому договору может быть в каждой из таблиц. Если строк может быть больше, чем одна, то группировка просто необходимо.
Так что пока остается только второе - избавиться от HEAVING, а проверку делать в WHERE.

-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
28.08.2006, 09:47
    #33945943
Andrew Sagulin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Владимор Конев ... во-вторых, проверку наличия остатков нужно снести во фразы WHERE соответствующих секций UNION, а саму проверку сделать посредством [NOT] EXISTS. Надеюсь мысль понятна?
Это НЕ ПОЗВОЛИТ уйти от подзапросов, но позволит ЗНАЧИТЕЛЬНО облегчить жизнь серверу.

Мысль мне понятна (...наверное :) ), но вот выгода сомнительна. Если вынести подзапрос в where, то серверу придётся выполнять подзапрос для каждой строки таблицы счетов. И ещё неизвестно, что выйдет дешевле: результирущая сортировка (для группировки) и несколько подзапросов в having для относительно небольшой сгруппированной таблицы, или большое количество подзапросов и группировка малого количества данных. Впрочем, не зная реального распределения данных, трудно судить о выгодах...

Я тут ещё думал в следующем направлении: если сочетание контрагент/договор не может проходить одновременно по двум счетам, то группировку можно делать сразу по таблицам счетов, а потом объединять результат. В результате серверу придётся группировать две меньших выборки, а потом их объединять, что легче (в log(N) раз), чем группировать одну большую выборку.
...
Рейтинг: 0 / 0
28.08.2006, 10:56
    #33946160
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Andrew SagulinВпрочем, не зная реального распределения данных, трудно судить о выгодах...Совершенно полностью согласен.
С одной стороны имеем сортировку и последующую агрегацию большого массива данных + фильтрация полученного результата.
С другой стороны - предварительныя фильтрация данных + последующая сортировка и группировка.
При разных раскладах предпочтительней могут оказаться разные методы.
Но остаюсь при своем мнении - я бы предпочел тот вариант, на который тебя упорно пытаюсь натолкнуть :)
Могу, конечно, на досуге сделать тест-кейс и проверить оба варианта, но если честно, то лично мне лень это делать за автора вопроса... ;)
...
Рейтинг: 0 / 0
28.08.2006, 11:55
    #33946320
angro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
ну в конце концов я сделал так,

select
kontragent,
dogovor,
sum(summa62_01),
sum(summa62_02)
from (select
kontragent,
dogovor,
summa as summa62_01,
0 as summa62_02
from
schet62_01

union all

select
kontragent,
dogovor,
0 as summa62_01,
summa as summa62_02
from
schet62_02)
as s

where kontragent in (select kontragent from schet62_01) and
kontragent in (select kontragent from schet62_02)
group by kontragent, dogovor

Andrew Sagulin натолкнул на мысль, первый вариант даже стыдно показывать. Работает с нормальной скоростью.
...
Рейтинг: 0 / 0
28.08.2006, 12:09
    #33946385
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
angroну в конце концов я сделал так,

select
kontragent,
dogovor,
sum(summa62_01),
sum(summa62_02)
from (select
kontragent,
dogovor,
summa as summa62_01,
0 as summa62_02
from
schet62_01

union all

select
kontragent,
dogovor,
0 as summa62_01,
summa as summa62_02
from
schet62_02)
as s

where kontragent in (select kontragent from schet62_01) and
kontragent in (select kontragent from schet62_02)
group by kontragent, dogovor

Andrew Sagulin натолкнул на мысль, первый вариант даже стыдно показывать. Работает с нормальной скоростью.НУ, оно немного через не то место работает.
Вот так будет более по-человечески:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select kontragent,
       dogovor,
       sum(summa62_01),
       sum(summa62_02)
  from (
          select kontragent,
                 dogovor,
                 summa as summa62_01,
                  0  as summa62_02
            from schet62_01
           where kontragent in (select  kontragent from schet62_02)
          union all 
          select kontragent,
                 dogovor,
                  0  as summa62_01,
                 summa as summa62_02
            from schet62_02
           where kontragent in (select  kontragent from schet62_01)   
       ) as s
group by kontragent, dogovor
Получишь почти то, что предлагал я.

Вот только я-таки вот такое решение хотел увидеть:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select kontragent,
       dogovor,
       sum(summa62_01),
       sum(summa62_02)
  from (
          select kontragent,
                 dogovor,
                 summa as summa62_01,
                  0  as summa62_02
            from schet62_01
           where exists (select  null from schet62_02 where schet62_02.kontragent = schet62_01.kontragen)
          union all 
          select kontragent,
                 dogovor,
                  0  as summa62_01,
                 summa as summa62_02
            from schet62_02
           where exists (select  null from schet62_01 where schet62_02.kontragent = schet62_01.kontragen)
       ) as s
group by kontragent, dogovor
...
Рейтинг: 0 / 0
28.08.2006, 12:17
    #33946411
angro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
спасибо, так лучше
...
Рейтинг: 0 / 0
28.08.2006, 13:54
    #33946766
Andrew Sagulin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Владимор Конев[quot angro]ну в конце концов я сделал так,
...


А что делать, если контрагент фигурирует в другом счёте, но сумма остатка таки равна нулю, Например,

Код: plaintext
1.
2.
3.
4.
5.
контрагент3 | договор1 |   10   |    0
-------------------------------------------
контрагент3 | договор2 |   0    |    -10
-------------------------------------------
контрагент3 | договор3 |   0    |    10
-------------------------------------------

Или это невозможно по условиям задачи (я в бухгалтерии не силён)?
...
Рейтинг: 0 / 0
28.08.2006, 14:15
    #33946849
angro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
не должно быть, но возможно. Ничего критического не случится просто в отчёте будет пустая строчка. Да твой вариант это предусматривает.
...
Рейтинг: 0 / 0
29.08.2006, 04:47
    #33948325
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Andrew Sagulin Владимор Конев angroну в конце концов я сделал так,
...


А что делать, если контрагент фигурирует в другом счёте, но сумма остатка таки равна нулю, Например,

Код: plaintext
1.
2.
3.
4.
5.
контрагент3 | договор1 |   10   |    0
-------------------------------------------
контрагент3 | договор2 |   0    |    -10
-------------------------------------------
контрагент3 | договор3 |   0    |    10
-------------------------------------------

Или это невозможно по условиям задачи (я в бухгалтерии не силён)?А собственно в чем проблема-то? Никто же не мешает добавить дополнительное условие в проверку EXISTS. Ну типа такого:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
select kontragent,
       dogovor,
       sum(summa62_01),
       sum(summa62_02)
  from (
          select kontragent,
                 dogovor,
                 summa as summa62_01,
                  0  as summa62_02
            from schet62_01
           where  1  =  1 
             and summa !=  0  -- Исключаем нулевые суммы из первого счета
             and exists (-- Проверяем, чтобы по второму счету была не нулевая сумма: 
                           select null 
                             from schet62_02 
                            where schet62_02.kontragent = schet62_01.kontragen
                              and schet62_02.summa !=  0  
                        )
          union all 
          select kontragent,
                 dogovor,
                  0  as summa62_01,
                 summa as summa62_02
            from schet62_02
           where  1  =  1 
             and summa !=  0  -- Исключаем нулевые суммы из второго счета
             and exists (-- Проверяем, чтобы по первому счету была не нулевая сумма:
                           select null 
                             from schet62_01 
                            where schet62_02.kontragent = schet62_01.kontragen
                              and schet62_01.summa !=  0 
                        )
       ) as s
group by kontragent, dogovor
having sum(summa62_01) !=  0 
       or 
       sum(summa62_02)
Или я тебя не так понял???
...
Рейтинг: 0 / 0
29.08.2006, 04:49
    #33948326
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Владимор КоневНикто же не мешает добавить дополнительное условие в проверку EXISTS. Ну типа такого:
Ой, чуть-чуть не дописал запрос :)
Забыл во второе условие having добавить "неравно нулю".
Вот так оно будет правильней:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
select kontragent,
       dogovor,
       sum(summa62_01),
       sum(summa62_02)
  from (
          select kontragent,
                 dogovor,
                 summa as summa62_01,
                  0  as summa62_02
            from schet62_01
           where  1  =  1 
             and summa !=  0  -- Исключаем нулевые суммы из первого счета
             and exists (-- Проверяем, чтобы по второму счету была не нулевая сумма: 
                           select null 
                             from schet62_02 
                            where schet62_02.kontragent = schet62_01.kontragen
                              and schet62_02.summa !=  0  
                        )
          union all 
          select kontragent,
                 dogovor,
                  0  as summa62_01,
                 summa as summa62_02
            from schet62_02
           where  1  =  1 
             and summa !=  0  -- Исключаем нулевые суммы из второго счета
             and exists (-- Проверяем, чтобы по первому счету была не нулевая сумма:
                           select null 
                             from schet62_01 
                            where schet62_02.kontragent = schet62_01.kontragen
                              and schet62_01.summa !=  0 
                        )
       ) as s
group by kontragent, dogovor
having sum(summa62_01) !=  0 
       or 
       sum(summa62_02) !=  0 
...
Рейтинг: 0 / 0
29.08.2006, 04:52
    #33948328
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
Кажись понял, в чем мой косяк :)
Вот это условие в исходной постановке задачи я так и не заметил:
angroесли сделать having то тогда будет фильтроваться и по договорам, а надо только по контрагентам.
Вот что значит "хорошо отдохнуть" :)

-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
29.08.2006, 09:25
    #33948514
angro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
авторА что делать, если контрагент фигурирует в другом счёте, но сумма остатка таки равна нулю, Например,

контрагент3 | договор1 | 10 | 0
-------------------------------------------
контрагент3 | договор2 | 0 | -10
-------------------------------------------
контрагент3 | договор3 | 0 | 10
-------------------------------------------

после того как подумал, понял что в этом случае тоже должно попадать в отчёт
...
Рейтинг: 0 / 0
29.08.2006, 09:57
    #33948600
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
помогите с запросом
angroпосле того как подумал, понял что в этом случае тоже должно попадать в отчётНу тогда мой параноидальный вариант тебе должен подойти
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / помогите с запросом / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]