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

如何将SQL JOIN结果合并为单行?多ItemType预订数据处理

解决Booking记录按ItemType合并为单行的问题

要实现将同一BookingId下ItemType为1000和2000的记录合并为单行的需求,核心是行转列操作,你的原查询因自连接导致生成多行,以下是两种可行的解决方案:

方案一:GROUP BY + MAX(CASE) 通用写法

适用于绝大多数SQL数据库,逻辑清晰且兼容性强:

SELECT 
    B.BookingID,
    B.BookingDate,
    B.Name,
    MAX(CASE WHEN IM.ItemType = 1000 THEN IM.ItemName END) AS [ItemName(1000)],
    MAX(CASE WHEN IM.ItemType = 2000 THEN IM.ItemName END) AS [ItemName(2000)]
FROM BOOKINGS B
JOIN ItemMapping IM ON B.ItemCode = IM.Code
WHERE IM.ItemType IN (1000, 2000)
GROUP BY B.BookingID, B.BookingDate, B.Name
-- 可选:仅保留同时包含1000和2000类型的预订,取消注释下方行
-- HAVING COUNT(DISTINCT IM.ItemType) = 2

逻辑说明:

  • 通过CASE语句分别提取对应ItemType的ItemName,非目标类型的结果为NULL
  • 用MAX()聚合函数忽略NULL,将同一BookingId下的多行数据合并为单行
  • GROUP BY按预订唯一标识分组,确保每个BookingId仅返回一行

方案二:PIVOT 简洁写法(限支持PIVOT的数据库如SQL Server)

如果你的数据库支持PIVOT语法,可以用更简洁的方式实现:

SELECT 
    BookingID,
    BookingDate,
    Name,
    [1000] AS [ItemName(1000)],
    [2000] AS [ItemName(2000)]
FROM (
    SELECT 
        B.BookingID,
        B.BookingDate,
        B.Name,
        IM.ItemType,
        IM.ItemName
    FROM BOOKINGS B
    JOIN ItemMapping IM ON B.ItemCode = IM.Code
    WHERE IM.ItemType IN (1000, 2000)
) AS SourceTable
PIVOT (
    MAX(ItemName)
    FOR ItemType IN ([1000], [2000])
) AS PivotTable

逻辑说明:

  • 子查询先筛选出目标ItemType的基础数据
  • 利用PIVOT将ItemType的行值直接转换为列,通过MAX()聚合获取对应ItemName

原查询问题总结

  1. 自连接Bookings表导致同一BookingId生成多条互补记录(一行仅1000列有值,一行仅2000列有值),DISTINCT无法合并这类行
  2. ISNULL(I.ItemName, I.ItemName)属于冗余写法,直接使用I.ItemName即可
  3. WHERE条件的强匹配会过滤掉仅存在单一目标ItemType的预订,且自连接会产生不必要的笛卡尔积

内容的提问来源于stack exchange,提问作者Jenifer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:30:08