Dưới đây là một giải pháp dựa trên bộ sử dụng CTE và các chức năng cửa sổ.
ranked_matches
CTE chỉ định xếp hạng đối sánh gần nhất cho mỗi hàng trong TableA
cùng với xếp hạng đối sánh gần nhất cho mỗi hàng trong TableB
, sử dụng index
giá trị như một bộ ngắt kết nối.
best_matches
CTE trả về các hàng từ ranked_matches
có thứ hạng tốt nhất (giá trị xếp hạng 1) cho cả hai thứ hạng.
Cuối cùng, truy vấn bên ngoài sử dụng LEFT JOIN
từ TableA
tới best_matches
CTE để bao gồm TableA
các hàng không được chỉ định đối sánh tốt nhất do đối sánh đóng đã được chỉ định.
Lưu ý rằng điều này không trả về kết quả phù hợp cho hàng TableA chỉ số 3 được chỉ ra trong kết quả mẫu của bạn. Kết quả khớp cho hàng này là chỉ số TableB 3, hiệu số là 83. Tuy nhiên, hàng TableB đó gần khớp hơn với hàng chỉ mục TableA 2, chênh lệch 14 nên nó đã được chỉ định. Vui lòng làm rõ câu hỏi của bạn nếu đây không phải là điều bạn muốn. Tôi nghĩ rằng kỹ thuật này có thể được điều chỉnh cho phù hợp.
CREATE TABLE dbo.TableA(
[index] int NOT NULL
CONSTRAINT PK_TableA PRIMARY KEY
, value int
);
CREATE TABLE dbo.TableB(
[index] int NOT NULL
CONSTRAINT PK_TableB PRIMARY KEY
, value int
);
INSERT INTO dbo.TableA
( [index], value )
VALUES ( 1, 123 ),
( 2, 245 ),
( 3, 342 ),
( 4, 456 ),
( 5, 608 );
INSERT INTO dbo.TableB
( [index], value )
VALUES ( 1, 152 ),
( 2, 159 ),
( 3, 259 );
WITH
ranked_matches AS (
SELECT
a.[index] AS a_index
, a.value AS a_value
, b.[index] b_index
, b.value AS b_value
, RANK() OVER(PARTITION BY a.[index] ORDER BY ABS(a.Value - b.value), b.[index]) AS a_match_rank
, RANK() OVER(PARTITION BY b.[index] ORDER BY ABS(a.Value - b.value), a.[index]) AS b_match_rank
FROM dbo.TableA AS a
CROSS JOIN dbo.TableB AS b
)
, best_matches AS (
SELECT
a_index
, a_value
, b_index
, b_value
FROM ranked_matches
WHERE
a_match_rank = 1
AND b_match_rank= 1
)
SELECT
TableA.[index] AS a_index
, TableA.value AS a_value
, best_matches.b_index
, best_matches.b_value
FROM dbo.TableA
LEFT JOIN best_matches ON
best_matches.a_index = TableA.[index]
ORDER BY
TableA.[index];
CHỈNH SỬA:
Mặc dù phương pháp này sử dụng CTE, nhưng đệ quy không được sử dụng và do đó không giới hạn ở 32K đệ quy. Tuy nhiên, có thể có chỗ để cải thiện ở đây từ góc độ hiệu suất.