2012-04-17 13 views
5

Sto provando ad unire due tabelle insieme, ma ho un requisito dispari.SQL complicato Join

Normalmente mi sarebbe solo si uniscono in cui il record è per quel cliente e il codice corrisponde

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

Tuttavia, ciò che ho bisogno di fare è unirsi su tre righe della tabella di ricerca. L'ID che corrisponde e la riga prima e dopo (se esistono) in base all'ordinamento in un'altra colonna (Ordine). Devo quindi ordinare il risultato, con il record che corrisponde per primo, quindi il record di ricerca precedente, quindi il record di ricerca che era dopo il record corrispondente.

Qualche idea sul modo migliore per farlo?

Esempio:

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

Potresti fornire un esempio per chiarire? Inoltre, quale RDBMS –

+0

Quale RDBMS, per favore? Questo è più facile in quelle implementazioni che hanno funzioni OLAP ... E potresti per favore elencare su quali colonne _actual_ vuoi che le corrispondenze? Così com'è, non è chiaro da dove proviene 'ID', e la colonna' Order' (nota a margine - non è consigliabile nominare tabelle/colonne dopo le parole 'riservate' in SQL). –

+0

Sql Server, ho aggiunto un exmaple – CaffGeek

risposta

2

Non il più efficiente, o elegante, ma funziona!

Impostazione dati:

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 

La Query:

;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 

Dà:

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 non può solo +/- 1 dall'ordine, ci sono lacune – CaffGeek

+0

La risposta è stata aggiornata, ha aggiunto un altro CTE - Ammetto che questo è v. brutto ora! – Paddy

0

Edit: Se ci sono lacune nel campo ordine, creare una nuova colonna con 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

Non posso solo +/- 1 dall'ordine, ci sono spazi vuoti – CaffGeek