![](/img/trans.png)
[英]How do I get value corresponding to latest date in group to fill in null values in Oracle SQL?
[英]How do I fill in null values with all rows based on group in Oracle SQL 19?
我在 Oracle SQL 19 中有下表:
+--------------+--------------+-------------------+------------------+-------------------+
| Team | Team Ranking | Team Ranking Date | Player Join Date | Player |
+--------------+--------------+-------------------+------------------+-------------------+
| FC Barcelona | 1 | 15-Jul-20 | 15-Jul-20 | Lionel Messi |
| FC Barcelona | 1 | 15-Jul-20 | 15-Jul-20 | Luis Suarez |
| FC Barcelona | 1 | 15-Jul-20 | 15-Jul-20 | Antoine Griezmann |
| FC Barcelona | 1 | 15-Jul-20 | 15-Jul-20 | Ousmane Dembele |
| FC Barcelona | 3 | 16-Jul-20 | (null) | (null) |
| FC Barcelona | 5 | 17-Jul-20 | (null) | (null) |
| Real Madrid | 2 | 15-Jul-20 | 15-Jul-20 | Eden Hazard |
| Real Madrid | 2 | 15-Jul-20 | 15-Jul-20 | Sergio Ramos |
| Real Madrid | 2 | 15-Jul-20 | 15-Jul-20 | Karim Benzema |
| Real Madrid | 2 | 15-Jul-20 | 15-Jul-20 | Gareth Bale |
| Real Madrid | 2 | 15-Jul-20 | 16-Jul-20 | James Rodriguez |
| Real Madrid | 5 | 25-Jul-20 | (null) | (null) |
| Real Madrid | 2 | 28-Jul-20 | (null) | (null) |
+--------------+--------------+-------------------+------------------+-------------------+
我想用球隊的所有球員信息填寫上表中的 null 值。 換句話說,我希望結果如下所示:
+--------------+--------------+-------------------+------------------+-------------------+
| Team | Team Ranking | Team Ranking Date | Player Join Date | Player |
+--------------+--------------+-------------------+------------------+-------------------+
| FC Barcelona | 1 | 15-Jul-20 | 15-Jul-20 | Lionel Messi |
| FC Barcelona | 1 | 15-Jul-20 | 15-Jul-20 | Luis Suarez |
| FC Barcelona | 1 | 15-Jul-20 | 15-Jul-20 | Antoine Griezmann |
| FC Barcelona | 1 | 15-Jul-20 | 15-Jul-20 | Ousmane Dembele |
| FC Barcelona | 3 | 16-Jul-20 | 15-Jul-20* | Lionel Messi* |
| FC Barcelona | 3 | 16-Jul-20 | 15-Jul-20* | Luis Suarez* |
| FC Barcelona | 3 | 16-Jul-20 | 15-Jul-20* | Antoine Griezmann*|
| FC Barcelona | 3 | 16-Jul-20 | 15-Jul-20* | Ousmane Dembele* |
| FC Barcelona | 5 | 17-Jul-20 | 15-Jul-20* | Lionel Messi* |
| FC Barcelona | 5 | 17-Jul-20 | 15-Jul-20* | Luis Suarez* |
| FC Barcelona | 5 | 17-Jul-20 | 15-Jul-20* | Antoine Griezmann*|
| FC Barcelona | 5 | 17-Jul-20 | 15-Jul-20* | Ousmane Dembele* |
| Real Madrid | 2 | 15-Jul-20 | 15-Jul-20 | Eden Hazard |
| Real Madrid | 2 | 15-Jul-20 | 15-Jul-20 | Sergio Ramos |
| Real Madrid | 2 | 15-Jul-20 | 15-Jul-20 | Karim Benzema |
| Real Madrid | 2 | 15-Jul-20 | 15-Jul-20 | Gareth Bale |
| Real Madrid | 2 | 15-Jul-20 | 16-Jul-20 | James Rodriguez |
| Real Madrid | 5 | 25-Jul-20 | 15-Jul-20* | Eden Hazard* |
| Real Madrid | 5 | 25-Jul-20 | 15-Jul-20* | Sergio Ramos* |
| Real Madrid | 5 | 25-Jul-20 | 15-Jul-20* | Karim Benzema* |
| Real Madrid | 5 | 25-Jul-20 | 15-Jul-20* | Gareth Bale* |
| Real Madrid | 5 | 25-Jul-20 | 16-Jul-20* | James Rodriguez* |
| Real Madrid | 2 | 28-Jul-20 | 15-Jul-20* | Eden Hazard* |
| Real Madrid | 2 | 28-Jul-20 | 15-Jul-20* | Sergio Ramos* |
| Real Madrid | 2 | 28-Jul-20 | 15-Jul-20* | Karim Benzema* |
| Real Madrid | 2 | 28-Jul-20 | 15-Jul-20* | Gareth Bale* |
| Real Madrid | 2 | 28-Jul-20 | 16-Jul-20* | James Rodriguez* |
+--------------+--------------+-------------------+------------------+-------------------+
我在上表中為填寫的值加了星標。
在這個例子中,我只展示了每個團隊的兩個排名變化。 但是一個團隊的排名可以無限次地改變。
有人可以告訴我如何在 Oracle SQL 19 中執行此操作嗎?
任何幫助將不勝感激!
為了您的方便,下面是 sql 查詢生成 Oracle 中的表:
with tbl as (
select 'FC Barcelona' team, 1 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/15/2020 11:31', 'MM/DD/YYYY HH24:MI') player_join_date, 'Lionel Messi' player from dual union
select 'FC Barcelona' team, 1 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/15/2020 11:31', 'MM/DD/YYYY HH24:MI') player_join_date, 'Luis Suarez' player from dual union
select 'FC Barcelona' team, 1 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/15/2020 11:31', 'MM/DD/YYYY HH24:MI') player_join_date, 'Antoine Griezmann' player from dual union
select 'FC Barcelona' team, 1 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/15/2020 11:31', 'MM/DD/YYYY HH24:MI') player_join_date, 'Ousmane Dembele' player from dual union
select 'FC Barcelona' team, 3 team_ranking, to_date('7/16/2020 04:18', 'MM/DD/YYYY HH24:MI') team_ranking_date, null player_join_date, null player from dual union
select 'FC Barcelona' team, 5 team_ranking, to_date('7/17/2020 06:54', 'MM/DD/YYYY HH24:MI') team_ranking_date, null player_join_date, null player from dual union
select 'Real Madrid' team, 2 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/15/2020 11:31', 'MM/DD/YYYY HH24:MI') player_join_date, 'Eden Hazard' player from dual union
select 'Real Madrid' team, 2 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/15/2020 11:31', 'MM/DD/YYYY HH24:MI') player_join_date, 'Sergio Ramos' player from dual union
select 'Real Madrid' team, 2 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/15/2020 11:31', 'MM/DD/YYYY HH24:MI') player_join_date, 'Karim Benzema' player from dual union
select 'Real Madrid' team, 2 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/15/2020 11:31', 'MM/DD/YYYY HH24:MI') player_join_date, 'Gareth Bale' player from dual union
select 'Real Madrid' team, 2 team_ranking, to_date('7/15/2020 09:29', 'MM/DD/YYYY HH24:MI') team_ranking_date, to_date('7/16/2020 14:44', 'MM/DD/YYYY HH24:MI') player_join_date, 'James Rodriguez' player from dual union
select 'Real Madrid' team, 5 team_ranking, to_date('7/25/2020 10:02', 'MM/DD/YYYY HH24:MI') team_ranking_date, null player_join_date, null player from dual union
select 'Real Madrid' team, 2 team_ranking, to_date('7/28/2020 06:13', 'MM/DD/YYYY HH24:MI') team_ranking_date, null player_join_date, null player from dual
)
select *
from tbl
order by team, team_ranking_date, player_join_date
您需要單獨考慮帶有 null 播放器和非空播放器的集合。 直接取非空玩家的集合。 並為 rest 應用外連接和交叉連接,並通過UNION ALL
組合所有結果,如下所示:
with tbl2 as
(
select * from tbl where player is not null
union all
select tt1.team, tt2.team_ranking, tt2.team_ranking_date, tt1.player_join_date, tt1.player
from
(
(select t2.*
from ( select * from tbl where player is null ) t1
right join ( select * from tbl where player is not null ) t2 on t2.player = t1.player ) tt1
cross join
(select t1.*
from ( select * from tbl where player is null ) t1
left join ( select * from tbl where player is not null ) t2 on t2.player = t1.player ) tt2
)
)
select *
from tbl2
order by team, team_ranking_date, player_join_date
如果您只有一張表(正如您在問題中所寫),您應該為 TEAMS、PLAYERS、TEAMPLAYERS 和 TEAMRANKINGS 創建表。 一旦你有了這些表,你就可以編寫一個查詢來給你所需的結果。 (您只需要創建一次表。根據需要運行查詢...)
表
create table teams
as
select unique team from tbl ; -- TBL: your original table
create table players
as
select unique player from tbl where player is not null ;
-- map players <-> teams
create table teamplayers
as
select unique team, player, player_join_date
from tbl
where player is not null ;
-- each team will have multiple rankings
create table teamrankings
as
select unique team, team_ranking, team_ranking_date
from tbl ;
-- check:
select * from teams ; -- 2 rows
select * from players ; -- 9 rows
select * from teamplayers ; -- 9 rows
select * from teamrankings ; -- 6 rows
詢問
select
T.team
, TR.team_ranking
, TR.team_ranking_date
, TP.player_join_date
, P.player
from teams T
join teamplayers TP on T.team = TP.team
join players P on TP.player = P.player
join teamrankings TR on T.team = TR.team
order by T.team, TR.team_ranking_date, P.player
;
結果
TEAM TEAM_RANKING TEAM_RANKING_DATE PLAYER_JOIN_DATE PLAYER
_______________ _______________ ____________________ ___________________ ____________________
FC Barcelona 1 15-JUL-20 15-JUL-20 Antoine Griezmann
FC Barcelona 1 15-JUL-20 15-JUL-20 Lionel Messi
FC Barcelona 1 15-JUL-20 15-JUL-20 Luis Suarez
FC Barcelona 1 15-JUL-20 15-JUL-20 Ousmane Dembele
FC Barcelona 3 16-JUL-20 15-JUL-20 Antoine Griezmann
FC Barcelona 3 16-JUL-20 15-JUL-20 Lionel Messi
FC Barcelona 3 16-JUL-20 15-JUL-20 Luis Suarez
FC Barcelona 3 16-JUL-20 15-JUL-20 Ousmane Dembele
FC Barcelona 5 17-JUL-20 15-JUL-20 Antoine Griezmann
FC Barcelona 5 17-JUL-20 15-JUL-20 Lionel Messi
FC Barcelona 5 17-JUL-20 15-JUL-20 Luis Suarez
FC Barcelona 5 17-JUL-20 15-JUL-20 Ousmane Dembele
Real Madrid 2 15-JUL-20 15-JUL-20 Eden Hazard
Real Madrid 2 15-JUL-20 15-JUL-20 Gareth Bale
Real Madrid 2 15-JUL-20 16-JUL-20 James Rodriguez
Real Madrid 2 15-JUL-20 15-JUL-20 Karim Benzema
Real Madrid 2 15-JUL-20 15-JUL-20 Sergio Ramos
Real Madrid 5 25-JUL-20 15-JUL-20 Eden Hazard
Real Madrid 5 25-JUL-20 15-JUL-20 Gareth Bale
Real Madrid 5 25-JUL-20 16-JUL-20 James Rodriguez
Real Madrid 5 25-JUL-20 15-JUL-20 Karim Benzema
Real Madrid 5 25-JUL-20 15-JUL-20 Sergio Ramos
Real Madrid 2 28-JUL-20 15-JUL-20 Eden Hazard
Real Madrid 2 28-JUL-20 15-JUL-20 Gareth Bale
Real Madrid 2 28-JUL-20 16-JUL-20 James Rodriguez
Real Madrid 2 28-JUL-20 15-JUL-20 Karim Benzema
Real Madrid 2 28-JUL-20 15-JUL-20 Sergio Ramos
您還應該添加一些約束,例如
-- team names must be unique
alter table teams
add constraint teams_unique unique( team ) ;
-- player names must be unique
alter table players
add constraint players_unique unique( player ) ;
-- allow the user to add rankings for existing teams only
alter table teamrankings
add constraint team_fkey foreign key( team )
references teams( team ) ;
-- (existing) players can be added to existing teams only
alter table teamplayers
add (
constraint teamplayers_team_fkey foreign key( team )
references teams( team )
, constraint teamplayers_player_fkey foreign key( player )
references players( player )
) ;
如果您想添加更多排名,您只需插入 TEAMRANKINGS 表,並運行與之前相同的查詢(請參閱DBfiddle )。 請注意,您現在不需要插入 PLAYER_JOIN_DATE 和 PLAYER - 這是原始表的問題(即當您添加新排名時必須插入 NULL)。
insert into teamrankings( team, team_ranking, team_ranking_date )
values( 'Real Madrid', 7, sysdate ) ;
選擇
如果由於某種原因無法創建新表,您也可以使用與上述相同的查詢,但不要使用表名,而是放入我們用於創建 4 個表的查詢:
-- TBL: your original table
select
T.team
, TR.team_ranking
, TR.team_ranking_date
, TP.player_join_date
, P.player
from ( select unique team from tbl ) T
join (
select unique team, player, player_join_date
from tbl
where player is not null
) TP on T.team = TP.team
join (
select unique player from tbl where player is not null
) P on TP.player = P.player
join (
select unique team, team_ranking, team_ranking_date
from tbl
) TR on T.team = TR.team
order by T.team, TR.team_ranking_date, P.player
;
DBfiddle 在這里。
如果我理解正確,您有兩個“實體”要合並:一方面是不同球隊和排名的列表,另一方面是球員列表。
這個想法是 select 為其中每一個的不同值,然后交叉連接它們:
select *
from (select distinct team, team_ranking, team_ranking_date from tbl) t join
(select distinct team, player_join_date, player
from tbl
where player is not null
) p
using (team)
order by team, team_ranking_date, player_join_date;
這是一個 db<>fiddle。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.