PostgreSQL:如何将两列转多行、去重并过滤空值
解决方法
核心是利用**横向连接(CROSS APPLY/LATERAL JOIN)**实现行转列,同时在转列阶段直接过滤空值,完全不用重复编写那300行的长SQL。
不同数据库的具体实现
1. SQL Server 用 CROSS APPLY
把你的300行关联查询包装成CTE(公共表表达式),再通过CROSS APPLY配合VALUES拆分行并过滤空值:
WITH ArticleSupplierCTE AS ( -- 这里粘贴你那300行的关联查询代码,示例框架如下: SELECT a.artnum, s.supplier1name, s.supplier2name FROM article a JOIN supplier s ON a.supplier_id = s.id -- 剩下的业务逻辑代码... ) SELECT DISTINCT ac.artnum, suppliercombo.supplier_name FROM ArticleSupplierCTE ac CROSS APPLY ( VALUES (ac.supplier1name), (ac.supplier2name) ) AS suppliercombo(supplier_name) WHERE suppliercombo.supplier_name IS NOT NULL
2. PostgreSQL/MySQL 8.0+ 用 LATERAL JOIN
语法逻辑一致,仅替换横向连接的关键字:
WITH ArticleSupplierCTE AS ( -- 同样粘贴你的300行关联查询代码 SELECT a.artnum, s.supplier1name, s.supplier2name FROM article a JOIN supplier s ON a.supplier_id = s.id -- 剩下的业务逻辑代码... ) SELECT DISTINCT ac.artnum, suppliercombo.supplier_name FROM ArticleSupplierCTE ac LATERAL JOIN ( VALUES (ac.supplier1name), (ac.supplier2name) ) AS suppliercombo(supplier_name) WHERE suppliercombo.supplier_name IS NOT NULL
方法优势
- 长SQL仅需编写一次,彻底避免Union All重复代码的冗余问题
- 在转列环节直接过滤空值,从根源上消除artnum=102这类空行
- 保留
DISTINCT实现去重,完全匹配你的需求
如果你的数据库不支持CTE,也可以把长查询作为子查询嵌套,效果完全一致。
内容的提问来源于stack exchange,提问作者burned
相关产品推荐
相关产品推荐

