2012-04-17 70 views
5

我想加入两个表在一起,但有一个奇怪的要求。复杂的SQL加入

一般情况下我刚刚加入该纪录是为客户和代码匹配

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

不过,我需要做的是加入从查找表中三行。匹配的ID和前后的行(如果存在的话)基于另一列(Order)中的排序顺序。然后,我需要对结果进行排序,首先匹配的记录,然后是之前的查找记录,然后是匹配记录之后的查找记录。

有关完成此操作的最佳方法的任何想法?

例子:

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

你能否提供一个例子来澄清?另外,哪个RDBMS – 2012-04-17 15:43:57

+0

请问什么RDBMS?在具有OLAP函数的那些实现中,这更容易...并且可以列出您希望匹配的实际列?事实上,目前还不清楚“ID”来自哪里以及“Order”列(注意 - 不推荐在SQL中的'reserved'字之后命名表/列)。 – 2012-04-17 15:47:42

+0

Sql Server,我加了exmaple – CaffGeek 2012-04-17 15:51:35

回答

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 2012-04-17 17:27:12

+0

答案更新,增加了另一个CTE - 我承认这是现在讨厌的! – Paddy 2012-04-17 17:36:04

0

编辑:如果有顺序领域的空白,创建一个新列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 2012-04-17 17:27:36