将 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 结果的方法。
有没有办法将 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 结果的方法。