我无法想出一个更好的方法来说明这一点。
我有几张桌子:
Postcode | One | Two | Three
2000 | | |
2001 | | |
2002 | | |
等,此表中有10,000个邮政编码,One
,Two
和Three
列均为空。
我有另一张这样的表:
Postcode | details
2001 | "foo"
2020 | "bar"
基本上,第二个表有一些选择的邮政编码,以及一些东西。让我们说那里有2000个邮政编码。
我想要做的,我知道它不理想,填充第一个表的三个额外列,第二个表中的邮政编码在数字上最接近它(无论是更大的还是更小)。
到目前为止,我已经完成了这项工作(我的Postcode
列是varchar
}:
SELECT
A.Postcode
, ( SELECT
MAX(X.Postcode)
FROM (
SELECT
CAST(B.Postcode AS INT) AS 'Postcode'
, RANK() OVER (ORDER BY CAST(B.Postcode AS INT) ASC) AS 'rank'
FROM [TableB] B with(nolock)
WHERE CAST(B.Postcode AS INT) >= CAST(A.Postcode AS INT)
) X WHERE X.[rank] = 1
) AS ONE
FROM [TableA] A with(nolock)
这让我获得了第一个更高的邮政编码。但我需要它更高或更低,我需要三个,而不仅仅是一个。
我被困在这里。
答案 0 :(得分:3)
您可以使用ROW_NUMBER
和CROSS APPLY
的组合:
SELECT
a.PostCode,
b.One,
b.Two,
b.Three
FROM TableA a
CROSS APPLY(
SELECT
One = MAX(CASE WHEN RN = 1 THEN x.PostCode END),
Two = MAX(CASE WHEN RN = 2 THEN x.PostCode END),
Three = MAX(CASE WHEN RN = 3 THEN x.PostCode END)
FROM(
SELECT *,
RN = ROW_NUMBER() OVER(ORDER BY CAST(t.PostCode AS INT))
FROM(
SELECT TOP 3
PostCode,
Diff = ABS(CAST(PostCode AS INT) - CAST(a.PostCode AS INT))
FROM Tableb
WHERE
PostCode <> a.PostCode
ORDER BY ABS(CAST(PostCode AS INT) - CAST(a.PostCode AS INT)), CAST(PostCode AS INT)
)t
)x
)b
<强>结果强>
PostCode One Two Three
---------- ---------- ---------- ----------
2000 2001 2002 2003
2001 2000 2002 2003
2002 2000 2001 2003
示例数据
表A
PostCode One Two Three
---------- ---------- ---------- ----------
2000 NULL NULL NULL
2001 NULL NULL NULL
2002 NULL NULL NULL
表B
PostCode
----------
2000
2001
2002
2003
2004
2005
2006
2007
2008