首页 > 解决方案 > 在一段时间内应用/保持状态

问题描述

鉴于此数据集,John 每年都会对他的股票持有量进行快照。

我希望标记数据,以便他的投资组合中仍然存在的最早购买的股票被标记为主要。

例如,给定这个数据集



+------+------+-------+-------+
| 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 年,John 持有 ABC,这是 Primary,因为它是唯一的。

2021 年,John 持有 ABC,但也收购了 XYZ,但 ABC 仍然是他的主要,因为它是第一个被添加的。

2022年,John持有ABC和XYZ,并加入了JKL,但ABC仍然是他的主要。

2023 年,John 不再持有 ABC,因此 XYZ 被标记为主要。在同一年添加多只股票的情况下,我希望将最早的按字母顺序标记为主要。

我将如何做到这一点,无论是通过 PL/SQL 中的函数还是纯 SQL 中的函数?

标签: sqloracledateplsqlwindow-functions

解决方案


这是使用窗口函数的一种选择:

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子查询计算为 each 添加 each的第一年name。然后,外部查询使用该信息对具有相同nameyear的记录进行排名:获得第一个排名的记录获得标志。

DB Fiddlde 上的演示

姓名 | 年份 | 库存 | 价值 | IS_PRIMARY
:--- | ---: | :---- | ----: | :---------
约翰 | 2020 | 美国广播公司 | 123 | 是的       
约翰 | 2021 | 美国广播公司 | 123 | 是的       
约翰 | 2021 | XYZ | 200 | 无效的      
约翰 | 2022 | 美国广播公司 | 123 | 是的       
约翰 | 2022 | XYZ | 200 |       
约翰 | 2022 | JKL | 500 | 无效的      
约翰 | 2023 | XYZ | 200 | 是的       
约翰 | 2023 | JKL | 500 | 无效的      

推荐阅读