Для нескольких строк с одними и теми же полями сохраните одну с обновленными значениями и отметьте остальные - PullRequest
0 голосов
/ 25 июня 2019

Для нескольких строк с одинаковыми характеристиками, я надеюсь, два добавят несколько отметок / новых столбцов в исходную таблицу.

Исходная таблица как ниже:

ID    Start_date    End_Date    Amount
1     2005-01-01    2010-01-01    5
1     2000-07-01    2009-06-01    10
1     2017-08-01    2018-03-01    30

Я хочу сохранить одну запись с самой ранней датой начала, самой поздней датой окончания, добавленной суммой и индикатором, указывающим мне использовать эту запись. Для остальных просто воспользуйтесь индикатором, чтобы я не использовал его.

Обновленная таблица должна быть такой:

ID  Start_date  End_Date    Amount  Amount_new  Usable  Start          End
1   2005-01-01  2010-01-01  5         45         0     2000-07-01     2018-03-01
1   2000-07-01  2009-06-01  10                   1      
1   2017-08-01  2018-03-01  30                   1      

Неважно, какую строку сохранять, если есть одна строка с Usable = 0 и обновляются значения Amount_new, Start и End.

Если не учитывать конечную дату, я подумывал о группировке по ID и дате_запуска, а затем обновил столбец Usable и Amount_new первой строки. Однако у меня все еще есть проблема выбора первой строки из группы по группе. Учитывая, что End_Date делает мой разум еще более беспорядочным!

Может ли кто-нибудь помочь пролить свет на эту проблему?

Ответы [ 2 ]

0 голосов
/ 25 июня 2019

Следующий запрос должен делать то, что вы хотите:

CREATE TABLE #temp (ID INT, [Start_date] DATE, End_Date DATE, Amount NUMERIC(28,0), Amount_new NUMERIC(28,0), Usable BIT, Start [Date], [End] [Date])

INSERT INTO #temp (ID, [Start_date], End_Date, Amount) VALUES
(1,'2005-01-01','2010-01-01',5),
(1,'2000-07-01','2009-06-01',10),
(1,'2017-08-01','2018-03-01',30),
(2,'2001-07-01','2009-06-01',5),
(2,'2017-08-01','2019-03-01',35)

UPDATE t1

SET Amount_new = t2.[Amount_new],
    Usable = 1,
    Start = t2.[Start],
    [End] = t2.[End]

FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT 1)) AS RNO FROM #temp) t1

INNER JOIN
(
SELECT ID,[Start_date],[End_Date],[Amount]
    ,SUM(Amount) OVER(PARTITION BY ID) AS [Amount_new]
    ,MIN([Start_date]) OVER(PARTITION BY ID) AS [Start]
    ,MAX(End_Date) OVER(PARTITION BY ID) AS [End]
    ,ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT 1)) AS RNO
FROM #temp ) t2 ON t1.id = t2.id AND t2.rno = t1.RNO AND t2.RNO = 1

SELECT * FROM #temp

Результат, как показано ниже,

ID  Start_date  End_Date    Amount  Amount_new  Usable  Start       End
1   2005-01-01  2010-01-01  5       45          1       2000-07-01  2018-03-01
1   2000-07-01  2009-06-01  10      NULL        NULL    NULL        NULL
1   2017-08-01  2018-03-01  30      NULL        NULL    NULL        NULL
2   2001-07-01  2009-06-01  5       40          1       2001-07-01  2019-03-01
2   2017-08-01  2019-03-01  35      NULL        NULL    NULL        NULL
0 голосов
/ 25 июня 2019

Вы, кажется, хотите что-то вроде этого:

alter table original
    add amount_new int,
    add usable bit,
    add new_start,
    add new_end;

Затем вы можете обновить его с помощью оконных функций:

with toupdate as (
      select o.*,
             sum(amount) over (partition by id) as x_amount,
             (case when row_number() over (partition by id order by start_date) as x_usable,
             min(start_date) as x_start_date,
             max(end_date) as x_end_date
      from original o
     )
update toupdate
    set new_amount = x_amount,
        usable = x_usable,
        new_start = x_start_date,
        new_end = x_end_date;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...