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

Откуда:
Сообщений: 88
Добрый день. Есть подобная таблица:
автор
date val1 va2
02.02.2018 100 200
02.02.2018 100 200
05.02.2018 150
05.02.2018 150
05.02.2018 150
06.02.2018 100
06.02.2018 100
06.02.2018 100
06.02.2018 100

Как для строко с датой 2018-05-02 использовать значение поля val1, указанное для строк с date = 2018-02-02 ну и соответсвенно для строк с датой 2018-05-06 использовать значение поля val1, уже расчитаное значение val1 для date = 2018-02-05?
13 сен 18, 17:44    [21674025]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 391
загадочное условие, давайте подробнее.
нарисуйте какой результат должен быть.
13 сен 18, 22:18    [21674238]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 17906
RTFM LEAD(),LAG()
13 сен 18, 22:28    [21674245]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
demind10
Member

Откуда:
Сообщений: 10
Akina, а вдруг у Badhabit MS SQL 2008 ?
14 сен 18, 08:22    [21674334]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1062
demind10
Akina, а вдруг у Badhabit MS SQL 2008 ?
тогда - TOP 1 в [cross | outer] apply-подзапросе.
А вдруг у ТС сервер ниже 2005, то скалярный коррелированный ТОР-1-подзапрос в списке select.
А вдруг у ТС не MS SQL Server? Ведь и такое бывает.
14 сен 18, 08:29    [21674337]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
demind10
Member

Откуда:
Сообщений: 10
Щукина Анна, да это я так, придираюсь. Настроение просто отвратительное и иногда мне бы лучше помолчать, может за умного сойду. А так ваш ответ и ответ Akina, вероятно, полностью покрывает все возможные варианты.
14 сен 18, 11:16    [21674490]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
Badhabit
Member

Откуда:
Сообщений: 88
Да, вот поподробнее. (серевер 2016)
Есть такая таблица. Значения полей plus и minus повторяются (одинаковые) для строк с одной датой.
Надо расчтать новое поле in_calc для каждой строки по формуле in_calc (предыдущего дня) - minus (предыдущего дня) + plus (предыдущего дня) и результат проставить каждого текущего дня
для первого дня поле не in_calc расчитывается т.к. нет in_calc (предыдущего дня) и новое поле будет равно просто in первого дня.
Исходная таблица:
автор
zzz in minus plus data
1111111 100 10 5 02.02.2018
1111111 100 10 5 02.02.2018
1111111 100 10 5 02.02.2018
1111111 100 10 5 02.02.2018
1111111 100 10 5 02.02.2018
1111111 100 10 5 02.02.2018
1111111 100 10 5 02.02.2018
1111111 100 10 5 02.02.2018
1111111 100 10 5 02.02.2018
1111111 100 30 50 05.02.2018
1111111 100 30 50 05.02.2018
1111111 100 200 250 06.02.2018
1111111 100 200 250 06.02.2018
1111111 100 200 250 06.02.2018
1111111 100 1 5 07.02.2018
1111111 100 1 5 07.02.2018


Должна получться:
автор
zzz in minus plus data in_calc
1111111 100 10 5 02.02.2018 100
1111111 100 10 5 02.02.2018 100
1111111 100 10 5 02.02.2018 100
1111111 100 10 5 02.02.2018 100
1111111 100 10 5 02.02.2018 100
1111111 100 10 5 02.02.2018 100
1111111 100 10 5 02.02.2018 100
1111111 100 10 5 02.02.2018 100
1111111 100 10 5 02.02.2018 100
1111111 100 30 50 05.02.2018 95
1111111 100 30 50 05.02.2018 95
1111111 100 200 250 06.02.2018 115
1111111 100 200 250 06.02.2018 115
1111111 100 200 250 06.02.2018 115
1111111 100 1 5 07.02.2018 165
1111111 100 1 5 07.02.2018 165

Я сделал как-то так:
use test
select	
	zzz
	, [in]
	, minus
	, plus
	, data
	, iif(
		lag(DATA) OVER(order by DATA) <> DATA,
		iif(
			lag([in]) OVER(order by DATA) is null,
			[in],
			(lag([in]) OVER(order by DATA)) - (lag([minus]) OVER(order by DATA)) + (lag([plus]) OVER(order by DATA))
		),
		lag([in]) OVER(order by DATA)
	) 'in_calc'
from tbl

но соответвенно не получается расставить in_calc для каждой строки текущего дня и следовательно все расчеты сбиваются...
14 сен 18, 13:28    [21674668]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
iap
Member

Откуда: Москва
Сообщений: 46334
Badhabit,

каждая таблица в SQL должна иметь уникальный ключ.
Где он в вашей таблице?
Как можно обратиться к конкретной строке, если все значения совпадают в миллионе записей?
Что задаёт порядок строк в вашей таблице? Ничего? Как тогда можно рассуждать о "предыдущей дате"?
14 сен 18, 13:46    [21674699]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
msLex
Member

Откуда:
Сообщений: 5604
iap
каждая таблица в SQL должна иметь уникальный ключ.


Зачем же так категорично.
14 сен 18, 13:48    [21674702]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
Badhabit
Member

Откуда:
Сообщений: 88
iap, нет у меня уникального ключа. Теоритически можно пронумеровать строки, но не особо понимаю как это может
14 сен 18, 13:49    [21674704]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
Badhabit
Member

Откуда:
Сообщений: 88
порядок задается только датами, внутри для порядка нет
14 сен 18, 13:49    [21674707]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 391
with cteData (zzz, inv, minus, plus, date)
as (
              select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 10  ,5,   cast('02.02.2018' as date)
    union all select 1111111, 100, 30  ,50,  cast('05.02.2018' as date)
    union all select 1111111, 100, 30  ,50,  cast('05.02.2018' as date)
    union all select 1111111, 100, 200 ,250, cast('06.02.2018' as date)
    union all select 1111111, 100, 200 ,250, cast('06.02.2018' as date)
    union all select 1111111, 100, 200 ,250, cast('06.02.2018' as date)
    union all select 1111111, 100, 1   ,5,   cast('07.02.2018' as date)
    union all select 1111111, 100, 1   ,5,   cast('07.02.2018' as date)
) ,
cteCalcs
as (
    select d.zzz
         , d.inv
         , d.minus
         , d.plus
         , d.date
         , lead(d.date) over(order by d.date) as NextDate
         , d.inv + sum(d.plus - d.minus) over(order by d.date) as calc
    from (select distinct * from cteData) d
)
select d.*, isnull(c.calc, d.inv) as calc
from cteData d 
    left join cteCalcs c on c.NextDate = d.date and c.zzz = d.zzz
14 сен 18, 16:22    [21674902]     Ответить | Цитировать Сообщить модератору
 Re: Как использовать значение строки с предыдущей датой  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 391
а вообще зачем вам дубликаты в таблице?
смысл иметь одинаковые значения для одной даты?
14 сен 18, 16:32    [21674910]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить