Sql 在一段时间内应用/保持状态
根据这个数据集,约翰每年都有一张自己所持股票的快照 我希望对数据进行标记,以便将其投资组合中最早购买的股票(仍然存在)标记为主要股票 例如,给定此数据集Sql 在一段时间内应用/保持状态,sql,oracle,date,plsql,window-functions,Sql,Oracle,Date,Plsql,Window Functions,根据这个数据集,约翰每年都有一张自己所持股票的快照 我希望对数据进行标记,以便将其投资组合中最早购买的股票(仍然存在)标记为主要股票 例如,给定此数据集 +------+------+-------+-------+ | Name | Year | Stock | Value | +------+------+-------+-------+ | John | 2020 | ABC | 123 | | John | 2021 | ABC | 123 | | John | 20
+------+------+-------+-------+
| 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,因为它是唯一的一家,所以ABC是初级的
2021年,John持有ABC,但也收购了XYZ,但ABC仍然是他的主要业务,因为它是第一个加入的业务
2022年,约翰拥有ABC和XYZ,并增加了JKL,但ABC仍然是他的初选
2023年,John不再持有ABC,因此XYZ被标记为primary。在同一年添加多个股票的情况下,我希望按字母顺序将最早的股票标记为主要股票
我将如何做到这一点,无论是通过PL/SQL中的函数还是纯SQL中的函数 这里有一个使用窗口函数的选项:
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
子查询计算为每个名称
添加每个股票
的第一年。然后,外部查询使用该信息对具有相同名称
和年份
的记录进行排名:获得第一个排名的记录将获得标志
:
NAME | YEAR | STOCK | VALUE | IS_PRIMARY
:--- | ---: | :---- | ----: | :---------
John | 2020 | ABC | 123 | yes
John | 2021 | ABC | 123 | yes
John | 2021 | XYZ | 200 | null
John | 2022 | ABC | 123 | yes
John | 2022 | XYZ | 200 | null
John | 2022 | JKL | 500 | null
John | 2023 | XYZ | 200 | yes
John | 2023 | JKL | 500 | null
名称|年份|股票|价值|为|主要
:--- | ---: | :---- | ----: | :---------
约翰| 2020 | ABC | 123 |是
约翰| 2021 | ABC | 123 |是的
约翰| 2021 | XYZ | 200 |零
约翰| 2022 | ABC | 123 |是的
约翰| 2022 | XYZ | 200 |零
约翰| 2022 | JKL | 500 |零
约翰| 2023 | XYZ | 200 |是的
约翰| 2023 | JKL | 500 |零
下面是一个使用窗口函数的选项:
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
子查询计算为每个名称
添加每个股票
的第一年。然后,外部查询使用该信息对具有相同名称
和年份
的记录进行排名:获得第一个排名的记录将获得标志
:
NAME | YEAR | STOCK | VALUE | IS_PRIMARY
:--- | ---: | :---- | ----: | :---------
John | 2020 | ABC | 123 | yes
John | 2021 | ABC | 123 | yes
John | 2021 | XYZ | 200 | null
John | 2022 | ABC | 123 | yes
John | 2022 | XYZ | 200 | null
John | 2022 | JKL | 500 | null
John | 2023 | XYZ | 200 | yes
John | 2023 | JKL | 500 | null
名称|年份|股票|价值|为|主要
:--- | ---: | :---- | ----: | :---------
约翰| 2020 | ABC | 123 |是
约翰| 2021 | ABC | 123 |是的
约翰| 2021 | XYZ | 200 |零
约翰| 2022 | ABC | 123 |是的
约翰| 2022 | XYZ | 200 |零
约翰| 2022 | JKL | 500 |零
约翰| 2023 | XYZ | 200 |是的
约翰| 2023 | JKL | 500 |零