SQL新手求助:如何连接某列含不同值的两张SQL表?
嘿,别担心,我来帮你搞定这两张表的连接操作!首先咱们先明确核心关联条件:两张表的column1、column2、column3这三个字段是匹配的唯一标识,所有连接逻辑都要基于这三个字段来实现。
1. 基础关联:获取所有属性明细
如果你只是想把table1的每条记录和table2里对应的属性行关联起来,输出完整的属性条目,用INNER JOIN就可以轻松实现:
SELECT t1.column1, t1.column2, t1.column3, t2.attribute_name, t2.attribute_value FROM table1 t1 INNER JOIN table2 t2 ON t1.column1 = t2.column1 AND t1.column2 = t2.column2 AND t1.column3 = t2.column3;
这个查询会返回和你给出的table2结构对应的关联结果,把table1的基础字段和table2的属性一一对应起来:
sub1 2207 43 ENTITY_ID VIJAY
sub2 2207 45 ENTITY_ID SHANKAR
sub2 2207 45 ACTIVATION_DATE 01052018
sub3 2207 47 ENTITY_ID RISHI
sub3 2207 47 ACTIVATION_DATE 01042018
2. 扁平化属性:把属性转成独立列
如果你的需求是让每条table1的记录对应一行,同时把ENTITY_ID和ACTIVATION_DATE作为单独的列展示(这是键值对类型表最常见的需求),可以用两种方式实现:
方式一:条件聚合(兼容绝大多数数据库)
这种写法适配MySQL、PostgreSQL、SQL Server等几乎所有主流数据库,通用性极强:
SELECT t1.column1, t1.column2, t1.column3, -- 提取ENTITY_ID对应的属性值 MAX(CASE WHEN t2.attribute_name = 'ENTITY_ID' THEN t2.attribute_value END) AS entity_id, -- 提取ACTIVATION_DATE对应的属性值 MAX(CASE WHEN t2.attribute_name = 'ACTIVATION_DATE' THEN t2.attribute_value END) AS activation_date FROM table1 t1 -- 用LEFT JOIN确保即使table2没有对应属性,table1的记录也能被保留 LEFT JOIN table2 t2 ON t1.column1 = t2.column1 AND t1.column2 = t2.column2 AND t1.column3 = t2.column3 -- 按table1的主键分组,聚合出每个属性的唯一值 GROUP BY t1.column1, t1.column2, t1.column3;
这个查询会返回扁平化的结构,看起来更直观:
sub1 2207 43 VIJAY NULL
sub2 2207 45 SHANKAR 01052018
sub3 2207 47 RISHI 01042018
方式二:使用PIVOT(适用于Oracle、SQL Server等支持该语法的数据库)
如果你的数据库原生支持PIVOT语法,写法会更简洁优雅:
SELECT column1, column2, column3, ENTITY_ID, ACTIVATION_DATE FROM table1 t1 LEFT JOIN table2 t2 ON t1.column1 = t2.column1 AND t1.column2 = t2.column2 AND t1.column3 = t2.column3 PIVOT ( -- 取每个属性对应的唯一值 MAX(attribute_value) -- 指定要转成列的属性名称 FOR attribute_name IN ('ENTITY_ID' AS ENTITY_ID, 'ACTIVATION_DATE' AS ACTIVATION_DATE) );
这个查询的输出结果和条件聚合的方式完全一致,只是语法更简洁。
内容的提问来源于stack exchange,提问作者Vijay

