Outer Apply 合并 2 行为 1 行 2 列

Outer Apply combine 2 rows into 1 row and 2 columns

我正在尝试编写一个查询,将多个外部应用联接结果组合成单行数据。我玩过一些 CTE,但我就是想不通解决方案。

我想让多个连接结果显示为 1 行,第二个连接结果显示在第二列

SELECT 
     E.[EventId]
    ,S_ID.[EventType]
    ,null as [RootCause2]

 FROM [AOE_Workflow].[dbo].[Event] E

    outer apply
    (
    select * from [AOE_Workflow].[dbo].[EventTypes] S
    WHERE E.EventID=S.EventID
    ) S

    outer apply
    (
    select * from [AOE_Workflow].[dbo].[EventType] S_ID
    WHERE S_ID.[EventTypeId]=S.[EventTypeId]
    ) S_ID

ORDER BY eventID desc

你还在设计阶段,还是受限于现有的数据结构?

每个事件类型似乎都是它自己的实体,根本原因也是如此,即 EventType = 'No power' 可能有 'expired battery' 或 'bad alternator' 作为根本原因, 所以您会将根本原因加入事件而不是事件类型。

CREATE TABLE Event
( eventId int NOT NULL,
  eventTypeId int not null,
  rootCauseId int not null,
  CONSTRAINT e_pk PRIMARY KEY (eventId)
);

CREATE TABLE EventType
( eventTypeId int NOT NULL,
  eventTypeDescription int not null,
  CONSTRAINT et_pk PRIMARY KEY (eventTypeId)
);

CREATE TABLE EventRootCause
( rootCauseId int NOT NULL,
  rootCauseDescription int not null,
  CONSTRAINT rc_pk PRIMARY KEY (rootCauseId)
);

select
     e.eventId
    ,et.EventTypeDescription as EventType
    ,rc.rootCauseDescription as RootCause2
from
    Event e 
left join
    EventType et
        on
            e.eventTypeId = et.EventTypeId
left join
    RootCause rc
        on
            e.rootCauseId = rc.RootCauseId
order by e.eventId

如果我没有弄错,你的 outer apply 可以用简单的 LEFT JOIN 更容易地指定。

并排输出可以用PIVOT完成。对于给定的查询,没有隐式排序顺序。这意味着,它将是随机的,哪个是第一个,哪个是第二个(和 third/fourth)。在我的 SQL 中,当您将 (SELECT NULL) 更改为适当的内容时,您可以轻松控制排序。

SELECT p.*
FROM
(
    SELECT 
         E.[EventId]
        ,S_ID.[EventType]
        ,'EventType_' + CAST(ROW_NUMBER() OVER(PARTITION BY E.[EventId] ORDER BY(SELECT NULL)) AS VARCHAR(1)) AS ColumnName
    FROM [AOE_Workflow].[dbo].[Event] E
    LEFT JOIN [AOE_Workflow].[dbo].[EventTypes] S ON E.EventID=S.EventID
    LEFT JOIN [AOE_Workflow].[dbo].[EventType] S_ID ON S_ID.[EventTypeId]=S.[EventTypeId]
) AS tbl
PIVOT
(
    MIN(EventType) FOR ColumName IN(EventType_1,EventType_2,EventType_3,EventType_4)
) AS p