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
下面的代码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