假设我有一个值和类别表:
+--+-----+---+
|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
,虽然我确信这可以做到但我真的不知道从哪里开始。
答案 0 :(得分: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()