2015-04-24 1 views
2

Есть ли способ конвертировать UNION ALL в JOIN и по-прежнему получать аналогичный результат.Конвертировать UNION ALLs в JOINs

Ниже приведен пример запроса для иллюстрации:

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 клиент на многие CustomerIdentifiers 1 CustomerIdentifier для многого OrderDetails

(Это делает дерево)

Вот link на sql, необходимый для создания е таблицы, чтобы сделать мою выше работу запроса:

+2

Можете ли вы разместить структуры таблиц и ожидаемый результат в формате таблицы? – Kangkan

+0

@ Kangkan Я добавил их. – Vaccano

+1

«Есть ли способ конвертировать UNION ALL в JOIN»? Да, это легко. Просто полное внешнее соединение на 1 = 0 и используйте выражение case, чтобы вернуть правильный источник столбца. Но вы все равно не сможете использовать это в индексированном виде ... –

ответ

1

никогда не делал индексированного представления, но вы могли бы переписать запрос:

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 
+0

Все еще не может использовать это в индексированном виде. Но мне нравится его внешний вид. – Vaccano

1

Используйте переменные, так что вы можете получить все немного сделано с одной выберите и одной вставки , Например:

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); 
1

Вот некоторые псевдо код из 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 

Я не исследовал ли это нарушило бы требования индексированного представления, но это вы можете дублировать результаты UNION ALL с помощью JOIN.

Смежные вопросы