2012-04-17 5 views
5

Я пытаюсь объединить две таблицы вместе, но имею нечетное требование.Сложный SQL-присоединение

Обычно я бы просто присоединиться, где запись для этого клиента и код соответствует

SELECT * 
    FROM DataTable d 
    JOIN LookupTable l 
     ON d.LookupCode = l.LookupCode 
     AND d.Customer = l.Customer 

Однако то, что мне нужно сделать, это присоединиться три строки из таблицы перекодировки. Идентификатор, который соответствует, и строка до и после (если они существуют) на основе порядка сортировки в другом столбце (Заказ). Затем мне нужно отсортировать результат, с первой записью, а затем записью поиска, которая была раньше, а затем записью поиска, которая была после согласованной записи.

Любые мысли о наилучшем способе достижения этого?

Пример:

Lookup: 
Customer Code Order 
12345 A  1 
12345 B  2 
12345 C  3 
12345 D  4 
12345 E  5 
22222 A  1 
22222 B  2 
22222 D  4 
22222 E  5 

Data: 
Customer Code 
12345  B 
12345  D 
22222  B 
22222  D 

Result I need 
Customer Code 
12345  B 
12345  A 
12345  C 
12345  D 
12345  C 
12345  E 
22222  B 
22222  A 
22222  D 
22222  D 
22222  B 
22222  E 
+1

Не могли бы вы привести пример, чтобы уточнить? Кроме того, какие СУБД –

+0

Какие РСУБД, пожалуйста? Это проще в тех реализациях, у которых есть функции OLAP ... И не могли бы вы перечислить, в каких столбцах _actual_ вы хотите совпадения? Как бы то ни было, неясно, откуда приходит идентификатор, а столбец «Порядок» (сторона примечания - не рекомендуется указывать таблицы/столбцы после «зарезервированных» слов в SQL). –

+0

Sql Server, я добавил exmaple – CaffGeek

ответ

2

Не самый эффективный, или элегантный, но это работает!

установки данных:

CREATE TABLE LookupTable (Customer int, Code nvarchar(1), OrderCol int) 
CREATE TABLE DataTable (Customer int, Code nvarchar(1)) 

insert LookupTable values (12345,'A',1),(12345,'B',2),(12345,'C',3),(12345,'D',4),(12345,'E',5),(22222,'A',1),(22222,'B',2),(22222,'D',4),(22222,'E',5) 
insert DataTable values (12345,'B'),(12345,'D'),(22222,'B'),(22222,'D') 

select * from LookupTable 
select * from DataTable 

Запросов:

;with LookupCte as (
    SELECT *  
     , ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY OrderCol ASC) AS LookUpOrder 
    FROM LookupTable 
) 
, DataCTE as (
    SELECT dt.Customer 
     , dt.Code 
     , lu.LookUpOrder 
     , (lu.LookUpOrder - 1) AS OrderColNVe 
     , (lu.LookUpOrder + 1) AS OrderColPVe 
     , ROW_NUMBER() OVER (PARTITION BY dt.Customer ORDER BY dt.Code ASC) AS DataCteRowNumber 
    FROM DataTable dt 
    INNER JOIN LookupCte lu 
     ON lu.Customer = dt.Customer 
     AND lu.Code = dt.Code 

) 
, UnionCTE As (

    SELECT d.Customer 
     , d.Code 
     , d.DataCteRowNumber 
     , 1 AS [CustomOrder] 
    FROM DataCTE d 

    UNION ALL 

    SELECT lt.Customer 
     , lt.Code 
     , d.DataCteRowNumber 
     , 2 AS [CustomOrder] 
    FROM DataCTE d 
    INNER JOIN LookupCte lt on lt.Customer = d.Customer 
     AND lt.LookUpOrder = d.OrderColNVe 

    UNION ALL 

    SELECT lt.Customer 
     , lt.Code 
     , d.DataCteRowNumber 
     , 3 AS [CustomOrder] 
    FROM DataCTE d 
    INNER JOIN LookupCte lt on lt.Customer = d.Customer 
     AND lt.LookUpOrder = d.OrderColPVe 
) 
SELECT u.Customer 
    , u.Code 
FROM UnionCTE u 
ORDER BY u.Customer, u.DataCteRowNumber, u.CustomOrder 

Дает:

Customer Code 
----------- ---- 
12345  B 
12345  A 
12345  C 
12345  D 
12345  C 
12345  E 
22222  B 
22222  A 
22222  D 
22222  D 
22222  B 
22222  E 

(12 row(s) affected) 
+0

I не может просто +/- 1 из заказа, есть пробелы – CaffGeek

+0

Отвечено обновлено, добавлено еще одно CTE - я признаю, что это противно сейчас! – Paddy

0

Edit: Если есть пробелы в поле порядка, создать новый столбец с row_Number()

;with c as (
    Select d.Customer 
     , d.code 
     , l.order 
    from Data as d 
    inner join Lookup as l 
    on d.customer = l.Customer 
     and d.Code = l.Code 
    ) 
    select 
     c.Customer 
      , C.Code 
    from c 
    union all 
    Select 
     , c.Customer 
     , l.code 
    from c 
    inner join lookup as l 
    on c.Customer = l.Customer 
     and c.Order = l.Order + 1 
    Select 
     , c.Customer 
     , l.code 
    from c 
    inner join lookup as l 
    on c.Customer = l.Customer 
     and c.Order = l.Order - 1 
+0

Я не могу просто +/- 1 из заказа, есть пробелы – CaffGeek

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