返回给定阈值的第一个匹配

时间:2015-02-26 16:29:32

标签: tsql sql-server-2014

以下代码返回多个匹配项:

    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

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

;WITH CTE AS (
SELECT * 
     ,ROW_NUMBER() OVER (PARTITION BY Value ORDER BY Threshold DESC) rn 
FROM  #Thresholds )
SELECT * 
FROM CTE 
WHERE rn = 1

答案 2 :(得分:-1)

如果按升序插入阈值,则可以快捷一点

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