Хитрая перегородка в SQL - PullRequest
2 голосов
/ 13 июля 2020

У меня есть такая таблица

RID ID  DTE FLAG    AMT SUMAMT
1   1   2020-07-03 02:52:15.480 Y   10  NULL
2   1   2020-07-04 02:52:15.480 N   10  NULL
3   1   2020-07-05 02:52:15.480 N   10  NULL
4   1   2020-07-06 02:52:15.480 Y   10  NULL
5   1   2020-07-13 02:52:15.480 Y   10  NULL
6   2   2020-07-06 02:52:15.480 N   10  NULL
7   2   2020-07-13 02:52:15.480 Y   10  NULL

Мне нужен такой результат

RID ID  DTE FLAG    AMT SUMAMT
1   1   2020-07-03 02:52:15.480 Y   10  10
2   1   2020-07-04 02:52:15.480 N   10  NULL
3   1   2020-07-05 02:52:15.480 N   10  NULL
4   1   2020-07-06 02:52:15.480 Y   10  30
5   1   2020-07-13 02:52:15.480 Y   10  10
6   2   2020-07-06 02:52:15.480 N   10  NULL
7   2   2020-07-13 02:52:15.480 Y   10  20

Все, что мне нужно здесь сделать, это обновить столбец SUMAMT для 'Y' FLAG позиции. Здесь условие заключается в том, что всякий раз, когда мы находим ФЛАГ 'Y', нам нужно проверить, были ли в прошлом какие-либо позиции с пометкой "N" на основе DTE, если да, нам нужно использовать AMT для этих позиций и необходимо подвести итоги и обновить SUMAMT.

SELECT RID,ID,DTE,FLAG,AMT,SUM(AMT) OVER (PARTITION BY ID ORDER BY ID,DTE) FROM #T

Я пробовал выполнить вышеуказанный запрос, он дает текущую сумму, я не понимаю, как создать раздел, как указано ниже ...

RID ID  DTE FLAG    AMT SUMAMT
1   1   2020-07-03 02:52:15.480 Y   10  10

2   1   2020-07-04 02:52:15.480 N   10  NULL
3   1   2020-07-05 02:52:15.480 N   10  NULL
4   1   2020-07-06 02:52:15.480 Y   10  30

5   1   2020-07-13 02:52:15.480 Y   10  10

6   2   2020-07-06 02:52:15.480 N   10  NULL
7   2   2020-07-13 02:52:15.480 Y   10  20

Запрос на создание таблицы и вставку данных ...

CREATE TABLE #T
(
    RID INT IDENTITY(1, 1),
    ID INT,
    DTE DATETIME,
    FLAG VARCHAR(1),
    AMT INT,
    SUMAMT INT
)

INSERT INTO #T (ID, DTE, FLAG, AMT) 
VALUES (1, GETDATE() - 10, 'Y', 10),
       (1, GETDATE() - 9, 'N', 10),
       (1, GETDATE() - 8, 'N', 10),
       (1, GETDATE() - 7, 'Y', 10),
       (1, GETDATE(), 'Y', 10),
       (2, GETDATE() - 7, 'N', 10),
       (2, GETDATE(), 'Y', 10)

1 Ответ

2 голосов
/ 13 июля 2020

Спасибо за образец данных. это было очень полезно.

В запросе ниже мы разделили данные на две части:

  • Флаг 'Y'
  • Флаг 'N'

Теперь мы вычисляем сумму всех строк флага «N», которые попадают между двумя флагами «Y». для строк флага 'N' расчет не производится.

SELECT t.RID, t.id, t.dte,  t.amt,t.flag, isnull(t.amt+ot.sum_amt,amt)
from 
(SELECT 
RID,ID, DTE, ISNULL(LAG(DTE,1) OVER(PARTITION BY ID ORDER BY DTE),'19000101') AS Prev_Yes
, DTE as Current_Yes
,amt
,flag
FROM #t as cr WHERE Flag = 'Y') as t
OUTER APPLY
(SELECT SUM(AMT) FROM #t
WHERE flag = 'N' 
AND DTE > t.Prev_Yes AND DTE < t.Current_Yes
and ID = t.id) as ot(sum_amt) 
UNION ALL
SELECT RID, id, dte,  amt,flag, NULL AS SUM_AMT
FROM #t 
WHERE flag = 'N'
ORDER BY rid

+-----+----+-------------------------+-----+------+------------------+
| RID | id |           dte           | amt | flag | (No column name) |
+-----+----+-------------------------+-----+------+------------------+
|   1 |  1 | 2020-07-03 09:35:10.513 |  10 | Y    | 10               |
|   2 |  1 | 2020-07-04 09:35:10.513 |  10 | N    | NULL             |
|   3 |  1 | 2020-07-05 09:35:10.513 |  10 | N    | NULL             |
|   4 |  1 | 2020-07-06 09:35:10.513 |  10 | Y    | 30               |
|   5 |  1 | 2020-07-13 09:35:10.513 |  10 | Y    | 10               |
|   6 |  2 | 2020-07-06 09:35:10.513 |  10 | N    | NULL             |
|   7 |  2 | 2020-07-13 09:35:10.513 |  10 | Y    | 20               |
+-----+----+-------------------------+-----+------+------------------+


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...