Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помощь со сложным запросом  [new]
Asic
Member

Откуда:
Сообщений: 45
Добрый день!
Есть 2 таблицы. В табл. #x находится информация о промежутке времени, когда товар(id) стоил дешевле.
В табл. #y информация о продажах за каждый день. Нужно написать запрос, который бы выводил сумму qty за все промежутки времени, когда товар(id) стоил дешевле и сумму qty с равным промежутком времени за прошедшие даты и эти даты не должны пересекаться с датами из table #x, а если пересекаются тогда снова отнимать количество дней равное промежутку этих дат до тех пор пока ни одной из них не будет в table #x.

create table #x (id int, startdate date, enddate date)
insert #x
select 1, '2018-01-11', '2018-01-13' union all
select 1, '2018-01-14', '2018-01-16' union all
select 1, '2018-01-20', '2018-01-22


create table #y (id int, idate date, qty int)
insert #y
select 1, '2018-01-08', 3 union all
select 1, '2018-01-09', 4 union all
select 1, '2018-01-10', 5 union all
select 1, '2018-01-11', 2 union all
select 1, '2018-01-12', 3 union all
select 1, '2018-01-13', 1 union all
select 1, '2018-01-14', 1 union all
select 1, '2018-01-15', 3 union all
select 1, '2018-01-16', 6 union all
select 1, '2018-01-17', 5 union all
select 1, '2018-01-18', 3 union all
select 1, '2018-01-19', 2 union all
select 1, '2018-01-20', 3 union all
select 1, '2018-01-21', 3 union all
select 1, '2018-01-22', 5


Т.е. с 11/01 по 13/01 это 3 дня, значит отнимаем это количество дней = с 08/01 по 10/01(этих дат нет в table #x);
c 14/01 по 16/01 тоже 3 дня, отнимаем их = с 11/01 по 13/01(эти даты есть в table #x) значит нужно выбрать другие, которых нет
в table #x, тогда с дат что получили с 11/01 по 13/01 отнимаем количество дней = с 08/01 по 10/01(этих дат нет в table #x);

Результат:
6 - 12
10 - 12
11 - 10
13 авг 18, 16:50    [21640835]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
aleks222
Member

Откуда:
Сообщений: 985
1. Не надо валить все в кучу.
2. Сначала сгенерируйте интервалы "с равным промежутком времени за прошедшие даты и эти даты не должны пересекаться с датами из table #x".
3. Ну а посчитать "сумму qty за все промежутки времени" - это тривиально.
14 авг 18, 05:27    [21641250]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
Asic
Member

Откуда:
Сообщений: 45
aleks222,
Именно со 2ым пунктом и возникают трудности.
14 авг 18, 06:36    [21641264]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
Asic
Member

Откуда:
Сообщений: 45
Эта задача не решается в sql?
24 авг 18, 10:00    [21652738]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20536
Посмотри на вот это:

WITH y_not_in_x (id, idate, qty)
AS 
(
SELECT #y.id, #y.idate, #y.qty, ROW_NUMBER() OVER (ORDER BY #y.idate ASC) rn
FROM #y
LEFT JOIN #x ON #y.idate BETWEEN #x.startdate AND #x.enddate
WHERE #x.id IS NULL
)
SELECT id, idate, qty
FROM y_not_in_x
WHERE rn > (SELECT SUM(1+DATEDIFF(day, startdate, enddate))
            FROM #x
            GROUP BY 1)

Теоретически (а проверять тупо лениво) вернутся только последние по дате записи после выбрасывания из #y как записей, попадающих в #x, так и ещё такого же количества записей, в #x не попадающих. Если оно - дальше авось сгруппируешь самостоятельно...
24 авг 18, 10:13    [21652759]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1467
Asic,

в SQL люди даже умудряются задачи о рюкзаке решать... просто ваша словесная постановка задачи не располагает к желанию поучаствовать в её решении...
24 авг 18, 10:17    [21652770]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
Asic
Member

Откуда:
Сообщений: 45
Akina, при выполнении ошибка:
Сообщение 164, уровень 15, состояние 1, строка 37
Each GROUP BY expression must contain at least one column that is not an outer reference.
24 авг 18, 10:30    [21652786]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20536
Asic
при выполнении ошибка:

Ну уберите GROUP BY вообще...
WITH y_not_in_x (id, idate, qty, rn)
AS 
(
SELECT #y.id, #y.idate, #y.qty, ROW_NUMBER() OVER (ORDER BY #y.idate ASC)
FROM #y
LEFT JOIN #x ON #y.idate BETWEEN #x.startdate AND #x.enddate
WHERE #x.id IS NULL
)
SELECT id, idate, qty
FROM y_not_in_x
WHERE rn > (SELECT SUM(1+DATEDIFF(day, startdate, enddate))
            FROM #x)

Вот только вопрос... Вы показываете данные. В #x 3 записи общим чётом на 9 дней, в таблице #y 15 записей, из коих 9 ложатся в диапазоны из #x. Вы понимаете, что по Вашему алгоритму (выбросить из 15 записей 9 попадающих и ещё столько же) для вывода ни одной записи не останется?
24 авг 18, 11:04    [21652838]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
Asic
Member

Откуда:
Сообщений: 45
Akina,
Ничего не выводит этот запрос, а должно получиться
6 - 12
10 - 12
11 - 10
24 авг 18, 11:11    [21652843]     Ответить | Цитировать Сообщить модератору
 Re: Помощь со сложным запросом  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20536
Asic
Ничего не выводит этот запрос
Я для кого пишу
Akina
о Вашему алгоритму (выбросить из 15 записей 9 попадающих и ещё столько же) для вывода ни одной записи не останется
???
Asic
должно получиться
6 - 12
10 - 12
11 - 10
Что означают эти числа? я не понимаю, откуда они взяты и как получены.

Распишите весь свой алгоритм на показанных данных ПОЛНОСТЬЮ.
24 авг 18, 11:25    [21652865]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить