Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите с логикой расчета / 4 сообщений из 4, страница 1 из 1
28.12.2021, 17:33
    #40123667
Romanov-krd
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с логикой расчета
Есть таблица с данными месяц-ид-сумма, в некоторых случаях на определенные месяцы стоит null значение. Задача - если стоит 5 мес подряд null то выводим первый не null после них иначе минимальный где не null. На скрине графически как должно все выглядеть.
...
Рейтинг: 0 / 0
28.12.2021, 17:39
    #40123669
Romanov-krd
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с логикой расчета
Я пробовал оконными функциями пронумеровать сначала все данные, потом те где есть сумма, вычесть из первого второе. И выбрать там где разница > 5 но в итоге не учитывается порядок - именно 5 подряд. Пробовал так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
			select	id min(month) 
			FROM 
			(
				select	id,month
						count() OVER (PARTITION BY id order by month asc) as num
				from  t1 
				order by month
			) total
			left join
			(
				select	id,month
						count() OVER (PARTITION BY id order by month asc) as num
				from t2 where data is not null 
				order by month
			) not_null	on total.id=not_null.id and total.month=not_null.month
			where total.num-not_null.num >=5
...
Рейтинг: 0 / 0
28.12.2021, 17:57
    #40123670
Руслан Дамирович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с логикой расчета
Romanov-krd,
Классическая задача изменения данных.
Код: 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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
DROP TABLE IF EXISTS #data
;
CREATE TABLE #data (
  [id]    INT,
  [month] DATE,
  [check] TINYINT
)
;
INSERT INTO
  #data
VALUES
  ( 1, '20210101', 1 ),
  ( 1, '20210201', 1 ),
  ( 1, '20210301', 1 ),
  ( 1, '20210401', 0 ),
  ( 1, '20210501', 0 ),
  ( 1, '20210601', 0 ),
  ( 1, '20210701', 0 ),
  ( 1, '20210801', 0 ),
  ( 1, '20210901', 0 ),
  ( 1, '20211001', 1 ),
  ( 1, '20211101', 1 ),
  ( 1, '20211201', 1 )
;
WITH
flg AS (
  SELECT
    [id]    = [id],
    [month] = [month],
    [check] = [check],
    [gr]    = ROW_NUMBER() OVER ( PARTITION BY [id] ORDER BY [month] )
            - ROW_NUMBER() OVER ( PARTITION BY [id], [check] ORDER BY [month] )
  FROM
    #data
),
grp AS (
  SELECT
    [id]    = [id],
    [check] = [check],
    [from]  = MIN( [month] ),
    [till]  = MAX( [month] ),
    [test]  = LAG( DATEDIFF( MONTH, MIN( [month] ), MAX( [month] ) ) ) OVER ( PARTITION BY [id] ORDER BY MIN( [month] ) )
  FROM
    flg
  GROUP BY
    [id],
    [check],
    [gr]
)
SELECT
  *
FROM
  grp
WHERE
  [test] >= 5
;
...
Рейтинг: 0 / 0
28.12.2021, 18:15
    #40123674
Руслан Дамирович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с логикой расчета
Romanov-krd,

или можно так (в общем, смотря какая цель конкретно). ваш пример явно "упрощен" для вопроса на форуме
Код: 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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
DROP TABLE IF EXISTS #data
;
CREATE TABLE #data (
  [id]    INT,
  [month] DATE,
  [check] TINYINT
)
;
INSERT INTO
  #data
VALUES
  ( 1, '20210101', 1 ),
  ( 1, '20210201', 1 ),
  ( 1, '20210301', 1 ),
  ( 1, '20210401', 0 ),
  ( 1, '20210501', 0 ),
  ( 1, '20210601', 0 ),
  ( 1, '20210701', 0 ),
  ( 1, '20210801', 0 ),
  ( 1, '20210901', 0 ),
  ( 1, '20211001', 1 ),
  ( 1, '20211101', 1 ),
  ( 1, '20211201', 1 )
;
WITH
flg AS (
  -- Поиск начал непрерывных интервалов:
  SELECT
    [id]    = [id],
    [from]  = [month],
    [till]  = DATEADD( MONTH, 5, [month] ),
    [sog]   = CASE
                WHEN [month] <= MAX( DATEADD( DAY, 180, [month] ) )
                              OVER (
                                PARTITION BY
                                  [id]
                                ORDER BY
                                  [month]
                                ROWS BETWEEN
                                  UNBOUNDED PRECEDING AND 1 PRECEDING )
                  THEN 0 
                  ELSE 1 
                END
  FROM
    #data
  WHERE
        [check] = 1
),
grp AS (
-- Идентификация строк, образующих непрерывные интервалы:
  SELECT
    [id]    = [id],
    [from]  = [from],
    [till]  = [till],
    [sog]   = [sog],
    [gr]    = SUM( [sog] ) OVER( PARTITION BY [id] ORDER BY [from], [till] )
  FROM
    flg
)
SELECT
  [id]    = [id],
  [from]  = MIN( [from] ),
  [till]  = DATEADD( MONTH, -5, MAX( [till] ) )
FROM
  grp
GROUP BY
  [id],
  [gr]
;
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите с логикой расчета / 4 сообщений из 4, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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