SQLazy:多表按 ID 合并为单行

问题描述

将多个结构相似但列名不同的表按 ID 全外连接合并为宽表。4 个表结构类似,每个表 2 个字段,字段含义相同但名字不同(id、id2、id3、id4 都是 ID)。现在要将 4 个表按 ID 合并为单行,每个 ID 唯一一行,当 ID 不在某个表中时对应列取 NULL。

源数据

T1 table:

|-----|------|
| id | colA |
| 555 | A_OK |

T2 table:

|-----|------|
| id2 | colB |
| 555 | B_OK |
| 10 | Bx |

T3 table:

|-----|------|
| id3 | colC |
| 222 | C |

T4 table:

|-----|------|
| id4 | colD |
| 10 | Dx |

期望结果

|---------|-----|------|-----|------|-----|------|-----|------|
| ID_main | id | colA | id2 | colB | id3 | colC | id4 | colD |
| 10 | | | 10 | Bx ||| 10 | Dx |
| 222 | | | | | 222 | C |||
| 555 | 555 | A_OK | 555 | B_OK |||||

比如,ID=555 在 T1 和 T2 中都有记录,T3 和 T4 中没有,因此 id、colA、id2、colB 有值,id3/colC/id4/colD 为 NULL。

ID=222 只在 T3 中有记录,其他表都没有,因此只有 id3、colC 有值,其余均为 NULL。

ID=10 在 T2 和 T4 中有记录,T1 和 T3 中没有,因此 id2、colB、id4、colD 有值,其余为 NULL。

SQLazy 分步实现

核心思路:先用 derive 将各表的 ID 列统一命名为 ID_main,方便后续合并。然后从第一个表开始,逐表进行全外连接:每次用 join 将当前结果与下一个表按 ID_main 全外连接,再用 derive 和 nvl 函数将新增 ID 合并到 ID_main 列,如此逐表追加获得结果。

|----------|------------|--------------------------------------------------------------------------------|
| Name | Anchor | Statement |
| t1 | T1 | derive id as ID_main, id, colA |
| t2 | T2 | derive id2 as ID_main, id2, colB |
| t3 | T3 | derive id3 as ID_main, id3, colC |
| t4 | T4 | derive id4 as ID_main, id4, colD |
| r1 | t1 | join ID_main; with t2; ID_main; take id2, colB; full |
| r1b | | derive nvl(ID_main, id2) as ID_main, id, colA, id2, colB |
| r2 | | join ID_main; with t3; ID_main; take id3, colC; full |
| r2b | | derive nvl(ID_main, id3) as ID_main, id, colA, id2, colB, id3, colC |
| r3 | | join ID_main; with t4; ID_main; take id4, colD; full |
| | | derive nvl(ID_main, id4) as ID_main, id, colA, id2, colB, id3, colC, id4, colD |

下面逐一解释这些步骤。

第 1--4 步:统一各表的 ID 列名

derive id as ID_main, id, colA

对 T1--T4 分别用 derive 将各自不同的 ID 列名(id/id2/id3/id4)统一重命名为 ID_main。

第 5 步:全外连接 T1 和 T2

join ID_main; with t2; ID_main; take id2, colB; full

用 join 功能将 t1 与 t2 按 ID_main 进行全外连接。

第 6 步:合并 ID 列中的 NULL

derive nvl(ID_main, id2) as ID_main, id, colA, id2, colB

如果某条记录来自 t2 而 t1 中没有,则这条记录的 ID_main 为 NULL,这一步将把这种记录中的 ID_main 赋值为 t2.id2,从而确保 ID_main 列始终有值。不同的 SQL 实现本步骤时方言不同,比如 oracle 用 nvl,SQLServer 用 COALESCE,而 NSPL 统一使用 nvl 函数,将来编译时将根据数据库类型自动翻译成相应的方言。

第 7--8 步:重复追加 T3

join ID_main; with t3; ID_main; take id3, colC; full

derive nvl(ID_main, id3) as ID_main, id, colA, id2, colB, id3, colC

重复 join + derive 模式,将 T3 全外连接到当前结果中。每次追加一个表后,用 ifn 将新增的 ID 合并到统一的 ID_main 列。

第 9-10 步:重复追加 T4,得到最终结果

join ID_main; with t4; ID_main; take id4, colD; full

derive nvl(ID_main, id4) as ID_main, id, colA, id2, colB, id3, colC, id4, colD

编译生成 SQL

确认上述步骤后,SQLazy 编译器自动生成原生 SQL(SQL Server 语法):

复制代码
WITH t1 AS (
		SELECT id AS ID_main, id, colA
		FROM T1
	),
	t2 AS (
		SELECT id2 AS ID_main, id2, colB
		FROM T2
	),
	r1 AS (
		SELECT t1.ID_main, t1.id, t1.colA, t2.id2, t2.colB
		FROM t1
			FULL JOIN t2 ON ID_main = t2.ID_main
	),
	r1b AS (
		SELECT COALESCE(NULLIF(CAST(ID_main AS VARCHAR(10)), ''), NULLIF(CAST(id2 AS VARCHAR(10)), '')) AS ID_main
			, id, colA, id2, colB
		FROM r1
	),
	t3 AS (
		SELECT id3 AS ID_main, id3, colC
		FROM T3
	),
	r2 AS (
		SELECT r1b.ID_main, r1b.id, r1b.colA, r1b.id2, r1b.colB
			, t3.id3, t3.colC
		FROM r1b
			FULL JOIN t3 ON ID_main = t3.ID_main
	),
	r2b AS (
		SELECT COALESCE(NULLIF(CAST(ID_main AS VARCHAR(10)), ''), NULLIF(CAST(id3 AS VARCHAR(10)), '')) AS ID_main
			, id, colA, id2, colB, id3
			, colC
		FROM r2
	),
	t4 AS (
		SELECT id4 AS ID_main, id4, colD
		FROM T4
	),
	r3 AS (
		SELECT r2b.ID_main, r2b.id, r2b.colA, r2b.id2, r2b.colB
			, r2b.id3, r2b.colC, t4.id4, t4.colD
		FROM r2b
			FULL JOIN t4 ON ID_main = t4.ID_main
	)
SELECT COALESCE(NULLIF(CAST(ID_main AS VARCHAR(10)), ''), NULLIF(CAST(id4 AS VARCHAR(10)), '')) AS ID_main
	, id, colA, id2, colB, id3
	, colC, id4, colD
FROM r3

SQLazy 让你**用业务语言描述逻辑,而不是用 SQL 语法写嵌套查询。**SQLazy 的分步计算将多表合并拆解为统一列名、逐表全外连接、合并 ID 等多个独立步骤,每一步都可以独立验证中间结果。join 功能配合 derive 和 nvl 函数,可以灵活地处理合并后的数据,如重命名列、合并 NULL 值等。这种逐个追加表的策略比 SQL 中编写多个 FULL JOIN + COALESCE 的嵌套查询更加清晰可维护。

相关推荐
我的愿望是成为富婆1 小时前
2027校招准备:从Excel操作到数据分析,还缺业务、SQL与统计思维
sql·数据分析·excel
阿里云大数据AI技术14 小时前
StarRocks 与 Fluss 用一条 SQL 查实时与历史
人工智能·sql
千桐科技19 小时前
qData 数据中台专业版功能解析:告别 Excel 与 SQL 拼凑,打通系统合并的可追踪数据链路
数据库·sql·excel·qdata
ClouGence21 小时前
开源数据库管理工具 CloudDM 新版本上线,新增 AI SQL 助手,支持 Elasticsearch、崖山数据库
数据库·sql·elasticsearch
留岁21 小时前
【无标题】
sql
润乾软件21 小时前
TRAE + SQLazy MCP 自动化编写 SQL 实践
sql·sqlazy
ly76891 天前
PostgreSQL 执行计划深读:从 EXPLAIN 输出到代价模型驱动的 SQL 改写
数据库·sql·postgresql·explain·执行计划·代价模型
川石课堂软件测试1 天前
涨薪技术|0到1学会性能测试第8课-Analysis分析图
服务器·数据库·python·sql·jmeter·mysql·容器
我命由我123451 天前
SQL 检测脚本
java·数据库·sql·功能测试·单元测试·压力测试·可用性测试
我的愿望是成为富婆1 天前
2027校招|大数据管理与应用专业:从会用技术工具到解决业务问题
sql