连接表但只允许使用记录一次

Smu*_*202 6 t-sql sql-server sql-server-2016

CREATE TABLE #A (UpperLimit NUMERIC(4))
CREATE TABLE #B (Id NUMERIC(4), Amount NUMERIC(4))

INSERT INTO #A VALUES 
    (1000), (2000), (3000)
INSERT INTO #B VALUES 
    (1, 3100), 
    (2, 1900), 
    (3, 1800), 
    (4, 1700), 
    (5, 900), 
    (6, 800)
Run Code Online (Sandbox Code Playgroud)

给定这两个表,我想将表 A 连接到 B ON B.Amount < A.UpperLimit,但表 B 中的每条记录只能使用一次,因此所需的输出将是:

期望的输出

我可以通过将表 B 的记录放入临时表中,将光标悬停在表 A 上获取顶部记录 < UpperLimit 并从临时表或其他一些编程解决方案中删除该记录来轻松地做到这一点,但我想避免这种情况,我非常确定这可以通过“正常”(递归 CTE?分区?)查询来完成。

Tru*_*ong 1

您可以使用以下递归 CTE 实现所需的输出

WITH 
DATA AS
(
  SELECT * FROM #A A1 INNER JOIN #B B1 ON A1.UpperLimit >= B1.Amount
),
MA AS
(
  SELECT MIN(UpperLimit) AS MinLimit, MAX(UpperLimit) AS MaxLimit FROM #A
),
RESULT AS 
(
  -- Get the first record corresponding with maximum upper limit  
  SELECT * 
  FROM DATA D1
  WHERE NOT EXISTS 
        (SELECT 1 
        FROM DATA D2 
        WHERE D2.UpperLimit = D1.UpperLimit AND D2.Amount > D1.Amount)
        AND D1.UpperLimit = (SELECT MaxLimit FROM MA)
  
  -- Recursive get remain record corresponding with other upper limit 
  UNION ALL      
  SELECT D1.* 
  FROM RESULT R1 INNER JOIN DATA D1 
       ON (R1.UpperLimit > D1.UpperLimit AND R1.Id != D1.Id) 
  WHERE D1.UpperLimit >= (SELECT MinLimit FROM MA)
       AND NOT EXISTS 
        (SELECT 1 
        FROM DATA D2 
        WHERE D2.UpperLimit = D1.UpperLimit AND D2.Amount > D1.Amount AND D2.Id != R1.Id)   
)

SELECT DISTINCT * FROM RESULT ORDER BY UpperLimit DESC;
Run Code Online (Sandbox Code Playgroud)

演示: https: //dbfiddle.uk/Y-m0K6Mk