我想加入一个带有range定义的键的表。像这样的经典方法非常慢:
SELECT A.ID, B.Index
FROM table1 as A
INNER JOIN table2 as B
ON ID.Key BETWEEN B.IDfrom AND B.IDto
我有这组表:
IDfrom
和IDto
定义的范围不重叠。所以
从理论上讲,只有一列就足以确定是否有ID
落入指定的范围。由于我的表格很大,所提出的经典解决方案非常慢,因为SQL不知道IDfrom是按升序排序的,而且它必须检查Table2的每一行。
如果我缩小Table1的ID范围以使其说1000行,则查询工作得非常快。我能看到的唯一绝望的方法是在循环中处理所有内容,确定ID范围从1到1000,然后从1001到2000,依此类推。对我的问题没有更好的解决方案吗?
答案 0 :(得分:1)
我认为
The ranges defined by IDfrom and IDto do not overlap. So theoretically just one column would be enough to determine if ID falls into a specified range.
您可以尝试子查询,但我不知道它是否会更快:
DECLARE @Table1 TABLE ( ID INT )
DECLARE @Table2 TABLE
(
ID INT ,
IDFrom INT ,
IDTo INT
)
INSERT INTO @Table1
VALUES ( 1 ),
( 2 ),
( 3 ),
( 4 ),
( 5 ),
( 6 ),
( 7 ),
( 8 ),
( 9 ),
( 10 ),
( 11 ),
( 12 )
INSERT INTO @Table2
VALUES ( 1, 1, 3 ),
( 2, 4, 4 ),
( 3, 5, 10 ),
( 4, 11, 12 )
SELECT t1.ID AS ID1,
( SELECT MIN(ID)
FROM @Table2 t2
WHERE t2.IDTo >= t1.ID
) AS ID2
FROM @Table1 t1
输出:
ID1 ID2
1 1
2 1
3 1
4 2
5 3
6 3
7 3
8 3
9 3
10 3
11 4
12 4
答案 1 :(得分:1)
你可以尝试这个技巧。交错数据然后使用累积最大值。
select id, table2index
from (select id, max(index) over (order by id) as table2index, index
from (select id, NULL as index
from table1
union all
select index, index as index
from table2
) tt
) tt
where index is null;
注意:这假设table2
中的索引正在增加。此外,这需要SQL Server 2012+。并且,我保留了您的列名,即使它们会导致错误(index
是保留字)。