从表 A 中查找有效日期与表 B 中的记录最接近的记录

问题描述 投票:0回答:1

我有如下两张表:

表A:

身份证 年龄 部门 薪资 开始日期
1 30 A 1000 美元 2000年1月1日
1 31 B 1200 美元 2022年1月1日
2 25 C 1200 美元 2021年1月6日
2 26 A 1300 美元 2022年1月1日
3 34 D 1400 美元 2021年1月1日
3 35 C 1800 美元 2022年1月1日

表B:

身份证 薪资 开始日期
1 1500 美元 2022年1月6日
2 1800 美元 2022年1月1日
3 1600 美元 2021年1月6日

当表 A 和表 B 之间的 ID 和开始日期组合不匹配时,我想在表 A 中插入合成新记录。新记录应从表 A 中获取具有最接近开始日期的记录的年龄和部门来自表 B 中缺失的记录,以及表 B 中的工资和开始日期。

输出:

身份证 年龄 部门 薪资 开始日期
1 30 A 1000 美元 2000年1月1日
1 31 B 1200 美元 2022年1月1日
1 31 B 1500 美元 2022年1月6日
2 25 C 1200 美元 2021年1月6日
2 26 A 1300 美元 2022年1月1日
3 34 D 1400 美元 2021年1月1日
3 34 D 1600 美元 2021年1月6日
3 35 C 1500 美元 2022年1月1日

请帮助编写 SQL 查询来实现此目的。

我在识别表 A 中的行时遇到问题,这些行的 start_date 与表 B 中的记录最接近。

sql oracle closest
1个回答
0
投票

使用

UNION ALL
合并两个表,然后使用
LAST_VALUE
分析函数获取最新的
age
dept
值(当它们不存在时):

SELECT id,
       LAST_VALUE(age) IGNORE NULLS
         OVER (PARTITION BY id ORDER BY start_date) AS age,
       LAST_VALUE(dept) IGNORE NULLS
         OVER (PARTITION BY id ORDER BY start_date) AS dept,
       salary,
       start_date
FROM   (
  SELECT id, age, dept, salary, start_date
  FROM   table_a
UNION ALL
  SELECT id, NULL, NULL, salary, start_date
  FROM   table_b
)

对于样本数据:

CREATE TABLE table_a (ID, Age, Dept, Salary, Start_date) AS
SELECT 1, 30, 'A', 1000, DATE '2000-01-01' FROM DUAL UNION ALL
SELECT 1, 31, 'B', 1200, DATE '2022-01-01' FROM DUAL UNION ALL
SELECT 2, 25, 'C', 1200, DATE '2021-06-01' FROM DUAL UNION ALL
SELECT 2, 26, 'A', 1300, DATE '2022-01-01' FROM DUAL UNION ALL
SELECT 3, 34, 'D', 1400, DATE '2021-01-01' FROM DUAL UNION ALL
SELECT 3, 35, 'C', 1800, DATE '2022-01-01' FROM DUAL;

CREATE TABLE Table_B (ID, Salary, Start_date) AS
SELECT 1, 1500, DATE '2022-06-01' FROM DUAL UNION ALL
SELECT 2, 1800, DATE '2022-01-01' FROM DUAL UNION ALL
SELECT 3, 1600, DATE '2021-06-01' FROM DUAL;

输出:

身份证 年龄 部门 薪资 START_DATE
1 30 A 1000 2000-01-01 00:00:00
1 31 B 1200 2022-01-01 00:00:00
1 31 B 1500 2022-06-01 00:00:00
2 25 C 1200 2021-06-01 00:00:00
2 26 A 1300 2022-01-01 00:00:00
2 26 A 1800 2022-01-01 00:00:00
3 34 D 1400 2021-01-01 00:00:00
3 34 D 1600 2021-06-01 00:00:00
3 35 C 1800 2022-01-01 00:00:00

如果您想要

INSERT
缺失的行,那么从 Oracle 12 开始,您可以使用
LATERAL
连接和
FETCH FIRST ROW ONLY
查找每行
age
的最新
dept
table_b
值:

INSERT INTO table_a (id, age, dept, salary, start_date)
SELECT b.id, a.age, a.dept, b.salary, b.start_date
FROM   table_b b
       LEFT OUTER JOIN LATERAL (
         SELECT a.age, a.dept
         FROM   table_a a
         WHERE  a.id = b.id
         AND    a.start_date <= b.start_date
         ORDER BY start_date DESC
         FETCH FIRST ROW ONLY
       ) a
       ON 1 = 1;

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.