You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SQL将两张关联表数据合并为单ID单行的多列结构?

解决思路与SQL实现

要实现将Dates表中每个Term对应的DateStart、DateEnd转为列,且每个Customer ID仅占一行的需求,**条件聚合(CASE WHEN + 聚合函数)**是比单纯JOIN或PIVOT更灵活的方案——因为PIVOT通常只处理单个值列,而这里每个Term对应两个日期字段,条件聚合能直接处理这种场景。

假设最终目标表结构(以Term为Term1、Term2为例)

  • ID
  • First Name
  • Family Name
  • Term1_DateStart
  • Term1_DateEnd
  • Term2_DateStart
  • Term2_DateEnd
    ...

固定Term值的SQL实现(直接生成新表)

如果你的Term是固定的几个值(比如Term1、Term2、Term3),可以用以下SELECT INTO语句直接创建目标表:

SELECT 
    c.ID,
    c.[First Name],
    c.[Family Name],
    -- 提取Term1的日期
    MAX(CASE WHEN d.Term = 'Term1' THEN d.DateStart END) AS Term1_DateStart,
    MAX(CASE WHEN d.Term = 'Term1' THEN d.DateEnd END) AS Term1_DateEnd,
    -- 提取Term2的日期
    MAX(CASE WHEN d.Term = 'Term2' THEN d.DateStart END) AS Term2_DateStart,
    MAX(CASE WHEN d.Term = 'Term2' THEN d.DateEnd END) AS Term2_DateEnd,
    -- 如需更多Term,复制上述CASE块修改Term值即可
    MAX(CASE WHEN d.Term = 'Term3' THEN d.DateStart END) AS Term3_DateStart,
    MAX(CASE WHEN d.Term = 'Term3' THEN d.DateEnd END) AS Term3_DateEnd
INTO 
    NewCustomerDateTable
FROM 
    Customer c
LEFT JOIN 
    Dates d ON c.ID = d.ID
GROUP BY 
    c.ID, c.[First Name], c.[Family Name];

为什么之前的JOIN/DISTINCT方案失效?

  • 单纯JOIN会把每个Term对应的行都关联出来,导致一个Customer对应多行(每个Term一行),无法合并为单行。
  • 使用DISTINCT时,若同一Customer的不同Term字段有冲突(比如某个Term的DateStart为NULL,另一个不为NULL),DISTINCT会保留所有唯一组合的行,而不是合并后的单行结果,因此会丢失部分数据或仍有多余行。

动态Term值的扩展方案(如果Term不固定)

如果Term的值是动态变化的,需要用动态SQL生成对应的CASE语句,示例如下(以SQL Server为例):

DECLARE @cols NVARCHAR(MAX), @query NVARCHAR(MAX);

-- 生成所有需要的列名(每个Term对应Start和End列)
SELECT @cols = STRING_AGG(
    CONCAT(
        'MAX(CASE WHEN d.Term = ''', Term, ''' THEN d.DateStart END) AS ', QUOTENAME(Term + '_DateStart'), ',',
        'MAX(CASE WHEN d.Term = ''', Term, ''' THEN d.DateEnd END) AS ', QUOTENAME(Term + '_DateEnd')
    ), ','
)
FROM (SELECT DISTINCT Term FROM Dates) AS Terms;

-- 拼接完整SQL语句
SET @query = CONCAT(
    'SELECT c.ID, c.[First Name], c.[Family Name], ', @cols, ' INTO NewCustomerDateTable FROM Customer c LEFT JOIN Dates d ON c.ID = d.ID GROUP BY c.ID, c.[First Name], c.[Family Name];'
);

-- 执行动态SQL
EXEC sp_executesql @query;

内容的提问来源于stack exchange,提问作者R. Anterous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 12:29:53