我有如下两张表:
表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 中的记录最接近。
使用
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;