Применить / сохранить статус в течение определенного периода времени - PullRequest
1 голос
/ 02 мая 2020

Учитывая этот набор данных, Джон имеет снимок за год своих запасов.

Мне бы хотелось, чтобы данные были помечены так, чтобы самые ранние из купленных в его портфеле акций были помечены как первичные.

Например, с учетом этого набора данных



+------+------+-------+-------+
| Name | Year | Stock | Value |
+------+------+-------+-------+
| John | 2020 | ABC   |   123 |
| John | 2021 | ABC   |   123 |
| John | 2021 | XYZ   |   200 |
| John | 2022 | ABC   |   123 |
| John | 2022 | XYZ   |   200 |
| John | 2022 | JKL   |   500 |
| John | 2023 | XYZ   |   200 |
| John | 2023 | JKL   |   500 |
+------+------+-------+-------+



Мне бы хотелось, чтобы данные были помечены следующим образом:


+------+------+-------+-------+------------+
| Name | Year | Stock | Value | Is_Primary |
+------+------+-------+-------+------------+
| John | 2020 | ABC   |   123 | Yes        |
| John | 2021 | ABC   |   123 | Yes        |
| John | 2021 | XYZ   |   200 |            |
| John | 2022 | ABC   |   123 | Yes        |
| John | 2022 | XYZ   |   200 |            |
| John | 2022 | JKL   |   500 |            |
| John | 2023 | XYZ   |   200 | Yes        |
| John | 2023 | JKL   |   500 |            |
+------+------+-------+-------+------------+



В 2020 году Джон держит AB C, который является основным, поскольку он единственный.

В 2021 году Джон имеет AB C, но также приобрел XYZ, но AB C по-прежнему является его основным, поскольку он добавляется первым.

в 2022 году, Джон имеет AB C и XYZ, и добавил JKL, но AB C по-прежнему является его основным.

В 2023 году Джон больше не держит AB C, поэтому XYZ отмечен как основной. В ситуации, когда несколько акций добавляются в один и тот же год, я бы хотел, чтобы самые ранние в алфавитном порядке были помечены как первичные.

Как мне это сделать, будь то через функции в PL / SQL или в чистом виде SQL?

1 Ответ

0 голосов
/ 02 мая 2020

Вот один из вариантов использования оконных функций:

select name, year, stock, value,
    case when 
        row_number() 
            over(partition by name, year  order by first_year_added, stock)
        = 1 then 'yes' 
    end is_primary
from (
    select
        t.*,
        min(year) over(partition by name, stock) first_year_added
    from mytable t
) t 

Подзапрос вычисляет первый год, когда каждый stock был добавлен для каждого name. Затем внешний запрос использует эту информацию для ранжирования записей, имеющих одинаковые name и year: запись, которая получает первый ранг, получает флаг.

Демонстрация в DB Fiddlde :

NAME | YEAR | STOCK | VALUE | IS_PRIMARY
:--- | ---: | :---- | ----: | :---------
John | 2020 | ABC   |   123 | yes       
John | 2021 | ABC   |   123 | yes       
John | 2021 | XYZ   |   200 | <em>null</em>      
John | 2022 | ABC   |   123 | yes       
John | 2022 | XYZ   |   200 | <em>null</em>      
John | 2022 | JKL   |   500 | <em>null</em>      
John | 2023 | XYZ   |   200 | yes       
John | 2023 | JKL   |   500 | <em>null</em>      
...