2014-01-15 113 views
0

假设我有价值观和类别的表:如何比较每一行并获得最佳结果?

+--+-----+---+ 
|ID|value|cat| 
+--+-----+---+ 
|0 |1 |0 | 
+--+-----+---+ 
|1 |3 |0 | 
+--+-----+---+ 
|2 |2 |1 | 
+--+-----+---+ 
|3 |1.2 |1 | 
+--+-----+---+ 
|4 |1 |1 | 
+--+-----+---+ 

而且我想知道,对于每一行,其值最密切匹配的行的ID属于同一类别,我也想知道其中的差异。

因此,对于第ID=0行,正确的答案是ID=1,差异值将是2。正确的输出应该是这样:

+--+----------+----------+ 
|ID|difference|best match| 
+--+----------+----------+ 
|0 |2   |1   | 
+--+----------+----------+ 
|1 |2   |0   | 
+--+----------+----------+ 
|2 |0.8  |3   | 
+--+----------+----------+ 
|3 |0.2  |4   | 
+--+----------+----------+ 
|4 |0.2  |3   | 
+--+----------+----------+ 

我只是学习CROSS JOIN而我敢肯定,这是可以做到我真的不知道从哪里开始。

+1

我不明白这个问题如何更清晰。如果你不喜欢它,请提供一个关于如何澄清我想要做的事情的建议。 – arman

回答

2

你可以做到这一点自联接和利用结合的ROW_NUMBER()功能与MIN()

;WITH cte AS (SELECT a.ID aID 
        ,MIN(ABS(a.value - b.value)) diff 
        ,ROW_NUMBER() OVER(PARTITION BY a.ID ORDER BY MIN(ABS(a.value - b.value)))RN 
        ,b.ID bID 
       FROM Table1 a 
       JOIN Table1 b 
       ON a.cat = b.cat 
       AND a.ID <> b.ID 
       GROUP BY a.ID,b.ID) 
SELECT aID 
     ,diff 
     ,bID Best_Match 
FROM cte 
WHERE RN = 1 

演示:SQL Fiddle

如果你想在的情况下返回多行领带,你想要使用RANK()而不是ROW_NUMBER()

相关问题