将 UNION ALL 转换为 JOIN

Convert UNION ALLs to JOINs

有没有办法将 UNION ALL 转换为 JOIN 并仍然得到类似的输出。

这里有一个示例查询来说明:

DECLARE @customerIdentifierId BIGINT 
SET @customerIdentifierId = 2

SELECT  1 AS Tag, NULL AS Parent, cust.CustomerId AS CustomerId, 
        NULL AS CustomerIdentifierId, NULL AS OrderDetailId
FROM    Customer.CustomerIdentifier custIdent            
        JOIN Customer.Customer cust
            ON cust.CurrentCustomerIdentifierId = custIdent.CustomerIdentifierId
        JOIN detail.OrderDetail detail
            ON detail.CustomerIdentifierId = custIdent.CustomerIdentifierId
WHERE   custIdent.CustomerIdentifierId = @customerIdentifierId

UNION ALL

SELECT  2, 1, NULL, custIdent.CustomerIdentifierId, null
FROM    Customer.CustomerIdentifier custIdent            
        JOIN Customer.Customer cust
            ON cust.CurrentCustomerIdentifierId = custIdent.CustomerIdentifierId
        JOIN detail.OrderDetail detail
            ON detail.CustomerIdentifierId = custIdent.CustomerIdentifierId
WHERE   custIdent.CustomerIdentifierId = @customerIdentifierId

UNION ALL

SELECT  3, 1, NULL, null, detail.OrderDetailId
FROM    Customer.CustomerIdentifier custIdent            
        JOIN Customer.Customer cust
            ON cust.CurrentCustomerIdentifierId = custIdent.CustomerIdentifierId
        JOIN detail.OrderDetail detail
            ON detail.CustomerIdentifierId = custIdent.CustomerIdentifierId
WHERE   custIdent.CustomerIdentifierId = @customerIdentifierId

空值中是否包含空值并不重要,但我需要并集给出的单独行。

我试过 CROSS JOIN,但没有成功。我希望有其他 SQL 技巧可以做到这一点 (CROSS APPLY?)

以防万一,我的最终目标是让它在 SQL Server 的索引(物化)视图中工作。

这是我正在寻找的输出:

Tag         Parent      CustomerId           CustomerIdentifierId OrderDetailId
----------- ----------- -------------------- -------------------- --------------------
1           NULL        4                    NULL                 NULL
1           NULL        4                    NULL                 NULL
1           NULL        4                    NULL                 NULL
1           NULL        4                    NULL                 NULL
1           NULL        4                    NULL                 NULL
2           1           NULL                 2                    NULL
2           1           NULL                 2                    NULL
2           1           NULL                 2                    NULL
2           1           NULL                 2                    NULL
2           1           NULL                 2                    NULL
3           2           NULL                 NULL                 2
3           2           NULL                 NULL                 14
3           2           NULL                 NULL                 26
3           2           NULL                 NULL                 38
3           2           NULL                 NULL                 50

表是父子关系:

1 个客户到多个客户标识符 1 个 CustomerIdentifier 到多个 OrderDetails

(它造了一棵树)

这是创建表以使我的上述查询工作所需的 link 到 sql:

从未做过索引视图,但您可以重写查询:

INSERT INTO @xmlDataTable(Tag, Parent, [Customer!1!CustomerId],
            [CustomerIdentifier!2!CustomerIdentifierId], [OrderDetail!3!OrderDetailId])

SELECT  rows.*
FROM    Customer.CustomerIdentifier custIdent            
        JOIN Customer.Customer cust
            ON cust.CurrentCustomerIdentifierId = custIdent.CustomerIdentifierId
        JOIN [order].OrderDetail detail
            ON detail.CustomerIdentifierId = custIdent.CustomerIdentifierId
WHERE   detail.CustomerIdentifierId = @customerIdentifierId
OUTER APPLY (
   SELECT 1, NULL, cust.CustomerId, NULL, null
   UNION ALL
   SELECT  2, 1, NULL, custIdent.CustomerIdentifierId, null
   UNION ALL
   SELECT  3, 1, NULL, null, detail.OrderDetailId
) rows

使用变量,这样您就可以用一个 select 和一个插入来完成整个工作。例如:

DECLARE 
@CustomerId INT,
@OrderDetailId INT;

SELECT
    @CustomerID = cust.CustomerId,
    @OrderDetailID = detail.OrderDetailId
FROM    
    Customer.CustomerIdentifier custIdent
    INNER JOIN Customer.Customer cust ON cust.CurrentCustomerIdentifierId = custIdent.CustomerIdentifierId
    INNER JOIN [order].OrderDetail detail ON detail.CustomerIdentifierId = custIdent.CustomerIdentifierId
WHERE
    detail.CustomerIdentifierId = @customerIdentifierId;

INSERT INTO @xmlDataTable(Tag, Parent, [Customer!1!CustomerId],
            [CustomerIdentifier!2!CustomerIdentifierId], [OrderDetail!3!OrderDetailId])
VALUES
(1, NULL, @CustomerID , NULL, NULL),
(2, 1, NULL, @customerIdentifierId, NULL),
(3, 1, NULL, null, @OrderDetailID);

这里有一些伪代码,你可以用一种 hacky 的方式来做到这一点:

SELECT COALESCE(t1.Col1, t2.Col1, tN.Col1) AS Col1
, COALESCE(t1.Col2, t2.Col2, tN.Col2) AS Col2
, COALESCE(t1.ColN, t2.ColN, tN.ColN) AS ColN
FROM t1
FULL OUTER JOIN t2 ON 1=0
FULL OUTER JOIN tN ON 1=0

我还没有研究这是否会违反索引视图的要求,但这是一种可以使用 JOIN 复制 UNION ALL 结果的方法。