powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / помогите с запросом
19 сообщений из 19, страница 1 из 1
помогите с запросом
    #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
помогите с запросом
    #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
помогите с запросом
    #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
помогите с запросом
    #33945778
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrew SagulinРаботать будет, но медленно.
Код: plaintext
1.
2.
3.
4.
5.
select 
   ...
from ...
group by ...
having ...
Ну, в целом, Вы в правильном направлении идёте, товарищ! Вот только немного ещё подумать и будет вполне нормальный и очень неплохо работающий вариант.
Сам додумаешься или подсказать ;) ?
...
Рейтинг: 0 / 0
помогите с запросом
    #33945820
Andrew Sagulin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владимор КоневНу, в целом, Вы в правильном направлении идёте, товарищ! Вот только немного ещё подумать и будет вполне нормальный и очень неплохо работающий вариант.
Сам додумаешься или подсказать ;) ?

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

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

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

Я тут ещё думал в следующем направлении: если сочетание контрагент/договор не может проходить одновременно по двум счетам, то группировку можно делать сразу по таблицам счетов, а потом объединять результат. В результате серверу придётся группировать две меньших выборки, а потом их объединять, что легче (в log(N) раз), чем группировать одну большую выборку.
...
Рейтинг: 0 / 0
помогите с запросом
    #33946160
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Andrew SagulinВпрочем, не зная реального распределения данных, трудно судить о выгодах...Совершенно полностью согласен.
С одной стороны имеем сортировку и последующую агрегацию большого массива данных + фильтрация полученного результата.
С другой стороны - предварительныя фильтрация данных + последующая сортировка и группировка.
При разных раскладах предпочтительней могут оказаться разные методы.
Но остаюсь при своем мнении - я бы предпочел тот вариант, на который тебя упорно пытаюсь натолкнуть :)
Могу, конечно, на досуге сделать тест-кейс и проверить оба варианта, но если честно, то лично мне лень это делать за автора вопроса... ;)
...
Рейтинг: 0 / 0
помогите с запросом
    #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
помогите с запросом
    #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
помогите с запросом
    #33946411
angro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
спасибо, так лучше
...
Рейтинг: 0 / 0
помогите с запросом
    #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
помогите с запросом
    #33946849
angro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не должно быть, но возможно. Ничего критического не случится просто в отчёте будет пустая строчка. Да твой вариант это предусматривает.
...
Рейтинг: 0 / 0
помогите с запросом
    #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
помогите с запросом
    #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
помогите с запросом
    #33948328
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кажись понял, в чем мой косяк :)
Вот это условие в исходной постановке задачи я так и не заметил:
angroесли сделать having то тогда будет фильтроваться и по договорам, а надо только по контрагентам.
Вот что значит "хорошо отдохнуть" :)

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

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

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


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