return 首先匹配给定的阈值

return first match given threshold value

下面的代码returns多了一个匹配:

    IF OBJECT_ID('tempdb..#Thresholds') IS NOT NULL DROP TABLE #Thresholds

    CREATE TABLE #Thresholds(
        [Id] [INT] IDENTITY(1,1) NOT NULL,
        [Threshold] [FLOAT] NOT NULL
    )
    INSERT INTO #Thresholds ([Threshold]) 
    SELECT 0.076923 UNION 
    SELECT 0.153846 UNION
    SELECT 0.230769 UNION
    SELECT 0.307692 UNION
    SELECT 0.384615 UNION
    SELECT 0.461538 UNION
    SELECT 0.538461 UNION
    SELECT 0.615384 UNION
    SELECT 0.692307 UNION
    SELECT 0.76923 UNION
    SELECT 0.846153 UNION
    SELECT 0.923076 UNION
    SELECT 1

    IF OBJECT_ID('tempdb..#DataToBeJoined') IS NOT NULL DROP TABLE #DataToBeJoined

    CREATE TABLE #DataToBeJoined(
        [Value] [FLOAT] NOT NULL
    )
    INSERT INTO #DataToBeJoined ([Value]) 
    SELECT 0.25 UNION ALL
    SELECT 0.5 UNION ALL
SELECT 0.5 UNION ALL
    SELECT 0.1

SELECT 
    * 
FROM #DataToBeJoined AS a
INNER JOIN #Thresholds AS b ON a.Value >= b.Threshold

如下:

Value   Id  Threshold
0.1     1   0.076923
0.25    1   0.076923
0.25    2   0.153846
0.25    3   0.230769
0.5     1   0.076923
0.5     2   0.153846
0.5     3   0.230769
0.5     4   0.307692
0.5     5   0.384615
0.5     6   0.461538

我感兴趣的是只返回最接近的匹配如下:

 Value  Id  Threshold
    0.1     1   0.076923
    0.25    3   0.230769
    0.5     6   0.461538
0.5     6   0.461538

有什么想法吗?

PS:

找到这个初步的解决方案:

select *, 
   (select top 1 Threshold 
    from #Thresholds 
    where #Thresholds.Threshold >= t.Value
    order by ABS(t.Value - #Thresholds.Threshold)  desc) as Threshold
from #DataToBeJoined t
;WITH CTE AS (
SELECT * 
     ,ROW_NUMBER() OVER (PARTITION BY Value ORDER BY Threshold DESC) rn 
FROM  #Thresholds )
SELECT * 
FROM CTE 
WHERE rn = 1

我认为这得到了你想要的(至少我的查询的答案符合预期)。

SELECT Value, Id, Threshold FROM (
  SELECT *, ROW_NUMBER() 
    OVER (PARTITION BY Value ORDER BY ABS(Value - Threshold)) as rn
  FROM #DataToBeJoined AS a
  CROSS JOIN #Thresholds AS b
) as subselect
WHERE rn = 1

如果你按升序插入Threshold,那么可以缩短一点

select #DataToBeJoined.value,  max(#Thresholds.ID), max(#Thresholds.Threshold)
  from #DataToBeJoined
  join #Thresholds 
    on #Thresholds.value <= #DataToBeJoined.Value
 group by #DataToBeJoined.value  

如果顺序不对

select * 
from
(
select #DataToBeJoined.value,  #Thresholds.ID, #Thresholds.Threshold 
     , row_number() over (partition by #DataToBeJoined.value order by #Thresholds.Threshold desc) as rn
  from #DataToBeJoined
  join #Thresholds 
    on #Thresholds.value <= #DataToBeJoined.Value
) st 
where st.rn = 1