2012-04-17 13 views
5

Estoy tratando de unir dos tablas, pero tengo un requisito extraño.SQL complicado Únase

Normalmente me acaba de unirse, donde el registro es para que el Cliente y el Código coincide

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

Sin embargo, lo que tengo que hacer es unirse en tres filas de la tabla de consulta. El ID que coincide y la fila anterior y posterior (si existen) en función del orden de clasificación en otra columna (Pedido). Luego, debo ordenar el resultado, con el registro que coincida primero, luego el registro de búsqueda que estaba antes, luego el registro de búsqueda que estaba después del registro coincidente.

¿Alguna idea sobre la mejor manera de lograr esto?

Ejemplo:

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

¿Podría darnos un ejemplo para aclarar? Además, ¿qué RDBMS –

+0

qué RDBMS, por favor? Esto es más fácil en aquellas implementaciones que tienen funciones OLAP ... ¿Y podría indicar en qué columnas _actual_ desea que coincidan? Tal como está, no está claro de dónde viene el 'ID' y la columna' Order' (nota al margen: no se recomienda nombrar tablas/columnas después de las palabras 'reservadas' en SQL). –

+0

Sql Server, agregué un exmaple – CaffGeek

Respuesta

2

No es el más eficiente, o elegante, pero funciona!

configuración de datos:

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 consulta:

;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 

Da:

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 no puedo simplemente +/- 1 de la orden, hay lagunas – CaffGeek

+0

Respuesta actualizada, agregué otra CTE - ¡Admito que esto es v. desagradable ahora! – Paddy

0

Editar: Si hay lagunas en el campo orden, crear una nueva columna 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

No puedo simplemente +/- 1 de la orden, hay lagunas – CaffGeek

Cuestiones relacionadas