Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Счёт-Фактура / 11 сообщений из 11, страница 1 из 1
16.09.2021, 14:39
    #40098036
LightN
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура


Всем добрый день. Вот такая задача: есть один счёт (Invoice). По нему есть Приход и есть Расход.
ааа - пришло 10(2,1,2,3,2), ушло - 10(6,4)
bbb - пришло 10(1,3,2,4), ушло - 10(7,3)
ccc - пришло 10(4,1,5), ушло - 10(2,8)
Нужно получить Расход (Счёт-Фактуру, как результат Var1 или Var2) с атрибутами прихода (ГТД & Кол-во), так, чтобы ORDER BY в Приходе и Расходе был по дате, а кол-во выбиралось из Расхода сверху вниз.
Т.е. если нужно отдать товар ааа -12.01.21=4шт., то имеем ввиду то, что aaa - уже отдавалось ранее 6 шт. и берем (т.е. начинаем брать) с Прихода STU=3-1=2 и далее вниз по таблице Прихода пока кол-во не будет равно Расходу.
У меня эта задача решена процедурой + функцией с 2-мя курсорами, что сильно грузит БД. Данная задача каким-то способом решается в 1С, но к сожалению у меня клиентская часть не 1С. М.б. кто-то уже решал такую задачу или м.б. видит простой способ с хитрыми JOIN, так, чтобы это выглядело оптимально?
...
Рейтинг: 0 / 0
16.09.2021, 16:08
    #40098079
bideveloper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
LightN,

картинок не видно
...
Рейтинг: 0 / 0
16.09.2021, 16:12
    #40098082
msLex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
Код: sql
1.
[img=http://c/Users/vovad/Desktop/SF.jpg]
...
Рейтинг: 0 / 0
16.09.2021, 16:26
    #40098090
LightN
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
https://disk.yandex.ru/i/FsE-yzI4rRNPwA
Пробовал по разному, картинки не проходят #img=# , ни через [выберите файл] ... jpg, png, gif не лезут.
Gif пролез!!!
...
Рейтинг: 0 / 0
16.09.2021, 17:50
    #40098108
Oleg_SQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
LightN,

Код: sql
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.
DECLARE @out TABLE(pn  VARCHAR(20), qty INT, dt  DATE);
DECLARE @in TABLE(pn   VARCHAR(20), dt   DATE, GTD  VARCHAR(20), qtyg INT);

insert @out values ('aaa', 6, '20210109'),('ccc', 2, '20210109'),('bbb', 7, '20210110'),
                   ('ccc', 8, '20210112'),('aaa', 4, '20210112'),('bbb', 3, '20210112')

insert @in values ('aaa', '20210101', 'ABC', 2),('aaa', '20210101', 'ABC2', 1),('bbb', '20210101', 'DEF', 1),
                  ('bbb', '20210101', 'DEF2', 3),('ccc', '20210101', 'JHI', 4),('aaa', '20210104', 'GKL', 2),
		  ('bbb', '20210104', 'MNO', 2),('ccc', '20210104', 'PQR', 1),('aaa', '20210107', 'STU', 3),
		  ('aaa', '20210107', 'STU2', 2),('bbb', '20210107', 'VWX', 4),('ccc', '20210107', 'YZA', 5)

;WITH nums
     AS (SELECT ROW_NUMBER() OVER(ORDER BY 1 / 0) AS n
           FROM STRING_SPLIT(REPLICATE(CAST(' ' AS VARCHAR(MAX)), 10000 - 1), ' ')),
     cte
     AS (SELECT ROW_NUMBER() OVER(PARTITION BY i.pn ORDER BY i.dt) AS rn, 
                i.pn AS pn2, i.dt AS dt2, i.GTD, x.qtyg
           FROM @in AS i
                OUTER APPLY (SELECT TOP (i.qtyg) 1 AS qtyg 
				      FROM nums
				    ORDER BY n) AS x),
     cte1
     AS (SELECT *
           FROM (SELECT *, 
                        _from = ISNULL(LAG(qty) OVER(PARTITION BY pn ORDER BY dt), 0) + 1, 
                        _to = SUM(qty) OVER(PARTITION BY pn ORDER BY dt)
                   FROM @out) AS o
          OUTER APPLY (SELECT * 
		                FROM cte AS i
		              WHERE i.pn2 = o.pn AND i.dt2 <= o.dt AND i.rn BETWEEN o._from AND o._to) AS i)
     SELECT pn, qty, dt, gtd, SUM(qtyg) AS qtyg
       FROM cte1
      GROUP BY pn, qty, dt, gtd
     ORDER BY dt, pn, gtd;



Я предварительно все строки "разбил" на число строк равное указанному кол-ву.
Например строка с кол-вом 6 заменяется 6-ю строками с кол-вом 1. Чтобы был корректный перенос по датам.
...
Рейтинг: 0 / 0
16.09.2021, 18:55
    #40098135
LightN
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
Oleg_SQL
LightN,

Код: sql
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.
DECLARE @out TABLE(pn  VARCHAR(20), qty INT, dt  DATE);
DECLARE @in TABLE(pn   VARCHAR(20), dt   DATE, GTD  VARCHAR(20), qtyg INT);

insert @out values ('aaa', 6, '20210109'),('ccc', 2, '20210109'),('bbb', 7, '20210110'),
                   ('ccc', 8, '20210112'),('aaa', 4, '20210112'),('bbb', 3, '20210112')

insert @in values ('aaa', '20210101', 'ABC', 2),('aaa', '20210101', 'ABC2', 1),('bbb', '20210101', 'DEF', 1),
                  ('bbb', '20210101', 'DEF2', 3),('ccc', '20210101', 'JHI', 4),('aaa', '20210104', 'GKL', 2),
		  ('bbb', '20210104', 'MNO', 2),('ccc', '20210104', 'PQR', 1),('aaa', '20210107', 'STU', 3),
		  ('aaa', '20210107', 'STU2', 2),('bbb', '20210107', 'VWX', 4),('ccc', '20210107', 'YZA', 5)

;WITH nums
     AS (SELECT ROW_NUMBER() OVER(ORDER BY 1 / 0) AS n
           FROM STRING_SPLIT(REPLICATE(CAST(' ' AS VARCHAR(MAX)), 10000 - 1), ' ')),
     cte
     AS (SELECT ROW_NUMBER() OVER(PARTITION BY i.pn ORDER BY i.dt) AS rn, 
                i.pn AS pn2, i.dt AS dt2, i.GTD, x.qtyg
           FROM @in AS i
                OUTER APPLY (SELECT TOP (i.qtyg) 1 AS qtyg 
				      FROM nums
				    ORDER BY n) AS x),
     cte1
     AS (SELECT *
           FROM (SELECT *, 
                        _from = ISNULL(LAG(qty) OVER(PARTITION BY pn ORDER BY dt), 0) + 1, 
                        _to = SUM(qty) OVER(PARTITION BY pn ORDER BY dt)
                   FROM @out) AS o
          OUTER APPLY (SELECT * 
		                FROM cte AS i
		              WHERE i.pn2 = o.pn AND i.dt2 <= o.dt AND i.rn BETWEEN o._from AND o._to) AS i)
     SELECT pn, qty, dt, gtd, SUM(qtyg) AS qtyg
       FROM cte1
      GROUP BY pn, qty, dt, gtd
     ORDER BY dt, pn, gtd;



Я предварительно все строки "разбил" на число строк равное указанному кол-ву.
Например строка с кол-вом 6 заменяется 6-ю строками с кол-вом 1. Чтобы был корректный перенос по датам.

Спасибо!
Проверю на скорость...
Я тоже использую STRING_SPLIT.
От него видно никуда не деться ...
...
Рейтинг: 0 / 0
16.09.2021, 19:54
    #40098143
Oleg_SQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
LightN,


Поправил немного, если данных больше, то _From нужно считать тоже накопительно:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
;WITH nums
     AS (SELECT ROW_NUMBER() OVER(ORDER BY 1 / 0) AS n
           FROM STRING_SPLIT(REPLICATE(CAST(' ' AS VARCHAR(MAX)), 10000 - 1), ' ')),
     cte
     AS (SELECT ROW_NUMBER() OVER(PARTITION BY i.pn ORDER BY i.dt, gtd) AS rn, 
                i.pn AS pn2, i.dt AS dt2, i.GTD, x.qtyg
           FROM @in AS i
                OUTER APPLY (SELECT TOP (i.qtyg) 1 AS qtyg 
                      FROM nums
                    ORDER BY n) AS x),
     cte1
     AS (SELECT *
           FROM ( SELECT *, _from = ISNULL(LAG(_to) OVER(PARTITION BY pn ORDER BY dt), 0) + 1 
                   FROM (SELECT *, _to = SUM(qty) OVER(PARTITION BY pn ORDER BY dt)
                          FROM @out) z) AS o
          OUTER APPLY (SELECT * 
                        FROM cte AS i
                      WHERE i.pn2 = o.pn AND i.dt2 <= o.dt AND i.rn BETWEEN o._from AND o._to) AS i)
     SELECT pn, qty, dt, gtd, SUM(qtyg) AS qtyg
       FROM cte1
      GROUP BY pn, qty, dt, gtd
     ORDER BY dt, pn, gtd;



Ну собственно, по мере использования могут возникать доработки, но направление есть )))
...
Рейтинг: 0 / 0
16.09.2021, 21:24
    #40098152
Oleg_SQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
LightN

Я тоже использую STRING_SPLIT.
От него видно никуда не деться ...


Много раз писали уже - создайте таблицу с нужным кол-вом строк (миллион, льярд или тп) и используйте ее всегда - серверу будет приятно )))
Я в примере привел nums за неимением ссылки на таковую
...
Рейтинг: 0 / 0
18.09.2021, 11:21
    #40098438
LightN
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
Oleg_SQL,
Спасибо, Спасибо. Ваше решение немного отличается от моего. Как я уже писал я тоже использовал split.
Мне казалось, что м.б. найдется какое-то иное решение без него. Какой-нибудь SQL-Перельман ткнет носом - ну вот же решение.
Ведь существует огромная потребность на join с такой структурой. И только 1С не напрягается этой проблемой.
Сотни тысяч компаний что-то перепродают, и конечно там есть qty прихода и qty расхода. И я вижу насколько востребовано JOIN на это решение. Видно как некоторые компании выпускают расходные документы, где таблицы идут по 1 штуке. Либо не додумались до split, либо там его нет, либо он стопорит систему своей работой, либо просто некуда деться. И там где можно обойтись 1 листом бумаги, приходит 10 страниц. Подождём MS, м.б. когда-то сделают ...
...
Рейтинг: 0 / 0
18.09.2021, 21:15
    #40098473
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
LightN
Как я уже писал я тоже использовал split.
Мне казалось, что м.б. найдется какое-то иное решение без него. Какой-нибудь SQL-Перельман ткнет носом - ну вот же решение.
Ну вот же решение:
Oleg_SQL
Много раз писали уже - создайте таблицу с нужным кол-вом строк (миллион, льярд или тп) и используйте ее всегда - серверу будет приятно )))
...
Рейтинг: 0 / 0
20.09.2021, 14:15
    #40098676
LightN
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Счёт-Фактура
alexeyvg ,
Вы меня неправильно поняли.
Таблицу с "льярд" конечно же создал, а вот печалька совсем в другом была.
Приход -Join(New)-Расход, и всё. И нет никаких ROW_NUMBER(), LAG() и OVER(PARTITION BY).
Ведь так работает любая складская или какая-нибудь другая распределительная система и запрос на такой именно системный join думаю очень был бы востребован ...

Oleg_SQL , ещё раз СПАСИБО. Внедрил, работает, быстрее ...
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Счёт-Фактура / 11 сообщений из 11, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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