在SQL(SSMS)中,我正在尝试使用范围表(类似于下面的Point_Lookup)进行查找,而我需要绕过NULL方案。
首先,请使用下面的SQL代码复制有问题的方案:
-- Code for People Data --
Create table #People ([Name] varchar(50) null,Age int null)
Insert into #People VALUES
('George' , 30),
('Clooney' , 18),
('Sandra' , 44),
('Bullock' , 15),
('Adam' , 100)
-- Code for Point_Lookup Data--
Create table #Point_Lookup ([Lower_Limit] int null, [Upper_Limit] int null, [Point] int null)
Insert into #Point_Lookup VALUES
(0, 10, 1),
(10, 20, 2),
(20, 30, 3),
(30, 40, 4),
(40, 50, 5),
(50, NULL, 6)
我尝试下面的代码成功连接两个表并获得期望的点,但[Age]> = 50时除外(由于Upper_Limit显示NULL,因此查找表中的点也显示NULL-期望的结果应为6 )。
Select ppl.*, point.[Point]
from #People as ppl
left join #Point_Lookup as point
on ppl.[Age] >= point.[Lower_Limit] and
ppl.[Age] < point.[Upper_Limit]
我也尝试过使用ISNULL()替换NULL,但是我意识到当[Age]> = 50(不太清楚为什么)时,这仍然不能联接两个表。
Select ppl.*, point.[Point]
from #People as ppl
left join #Point_Lookup as point
on ppl.[Age] >= point.[Lower_Limit]
and ppl.[Age] < isnull(point.[Upper_Limit], point.[Upper_Limit] + 1 + ppl.
[Age])
当[Age]> = 50(在Upper_Limit中不为NULL)时,是否有办法仅考虑一个条件->(ppl。[Age]> = point。[Lower_Limit])?也许以某种方式使用CASE?
[年龄]> = 50时,预期结果应显示6点。请帮忙。
答案 0 :(得分:3)
您可以尝试使用coalesce()
函数,该函数在某些情况下会起作用,因此,如果point。[Upper_Limit]为null,则它将考虑稍后使用
Select ppl.*, point.[Point]
from #People as ppl
left join #Point_Lookup as point
on ppl.[Age] >= point.[Lower_Limit]
and ppl.[Age] < coalesce(point.[Upper_Limit], point.[Lower_Limit] + 1 + ppl.
[Age])
答案 1 :(得分:3)
如果NULL
意味着应该避免该情况,那么您可以使用OR
来精确地写成这样:
Select
ppl.*,
point.[Point]
from
#People as ppl
left join #Point_Lookup as point on
ppl.[Age] >= point.[Lower_Limit] and
(point.[Upper_Limit] IS NULL OR ppl.[Age] < point.[Upper_Limit])
尝试:
isnull(point.[Upper_Limit], point.[Upper_Limit] + 1 + ppl.[Age])
如果point.[Upper_Limit]
是NULL
,那么任何加法也将是NULL
,这就是为什么它不能正确加入的原因。您应该删除point.[Upper_Limit]
并离开1 + ppl.[Age]
,它会起作用,但是使用OR
会更好地使用索引(如果有)。>
答案 2 :(得分:0)
尝试一下
Select ppl.*,
(select top 1 point from #Point_Lookup where ppl.Age>=Lower_Limit and ppl.Age<=(case when Upper_Limit is null then ppl.Age else Upper_Limit end) ) from #People as ppl
答案 3 :(得分:0)
这种结构的问题是,您可能会在范围内缺少或重叠,在这种情况下,也可能会造成混淆,对于等于某个限制之一的值,应该是正确的点...
我经常这样做,只有一个限制,边界是由上一条和下一条记录定义的,没有办法缺少超出范围的值
Create table #People ([Name] varchar(50) null,Age int null)
Insert into #People VALUES
('George' , 30),
('Clooney' , 18),
('Sandra' , 44),
('Bullock' , 15),
('Adam' , 100),
('Lio' , 4)
-- Code for Point_Lookup Data--
Create table #Point_Lookup ([Limit] int not null,[Point] int null)
Insert into #Point_Lookup VALUES
(0, 1),
(10, 2),
(20, 3),
(30, 4),
(40, 5),
(50, 6)
SELECT *
FROM
#People P
CROSS APPLY (
SELECT TOP 1 Point
FROM #Point_Lookup L
WHERE P.Age >= L.Limit
ORDER BY Limit DESC
) L
drop table #people
drop table #Point_Lookup