2016-03-02 58 views
1

enter image description hereSql Server - 如何获取最少限定记录?

如何获得最少的基于“年龄”我传递给查询?

而且年龄不是MINAGE或在表中最大生存周期的一部分。我的

例如存储过程

declare @MyAge int; 
select @MyAge = 21; 

select * 
from Mytable 
where (AssuranceId = 9 and MemberTypeId = 1) 
and ( @MyAge between MinAge and MaxAge) -- obvious this will return nothing 

- 但我想它去解决它返回该行与上最小和最大年龄排空值---如果它找到一个符合条件的行

- 因此,它应该返回行ID:16 或任何建议将理解

+0

但后来 - 如果我通过@MyAge = 38,它会给我...空年龄的行记录,但我确实有MinAge = 38记录? (@MyAge> = MinAge或MinAge为NULL)或(@MyAge <= MaxAge或MaxAge为NULL)>> Tim Biegeleisen-它不允许我评论你的回复/答案:( –

+0

有些事情是这样的' '? – wajeeh

+0

这是因为你的'BETWEEN'需要MinAge和MaxAge都成为现实 – jarlh

回答

0

查询的逻辑,如果我理解正确的话,是要保留所有记录@MyAgeMinAgeMaxAge之间,除了在情况下没有记录,在这种情况下,你想为哪个MinAge和记录MaxAge都是NULL。我看不到在这里使用子查询。我在WHERE子句中有一个子查询,它检查是否有任何范围匹配记录。如果是这样,那么它使用您以前的WHERE条件,如果没有,则它使用年龄栏上的检查IS NULL

SELECT * 
FROM Mytable 
WHERE (AssuranceId = 9 AND MemberTypeId = 1) AND TRUE = 
    CASE WHEN (SELECT COUNT(*) FROM Mytable WHERE @MyAge BETWEEN MinAge AND MaxAge) > 0 
     THEN (@MyAge >= MinAge AND @MyAge <= MaxAge) 
     ELSE (MinAge IS NULL AND MaxAge IS NULL) 
    END 

在这种情况下子查询的罚款应该很小,因为它不相关。

+0

SQL中的错误查询:关键字'BETWEEN'附近的语法不正确 –

+0

@BhekiNzuza围绕'THEN'子句添加括号。 –

+0

这就是我做的第一件事..但没有运气 –

1
declare @MyAge int; 
select @MyAge = 21; 

select * 
from Mytable 
where (AssuranceId = 9 and MemberTypeId = 1) 
and (isnull(@MyAge, 0) between isnull(MinAge, 0) and isnull(MaxAge, 200)) 

UPD

如果你想要一个最具体的记录,你可以添加顺序子句:

declare @MyAge int; 
select @MyAge = 38; 

select top 1 * 
from Mytable t 
where (AssuranceId = 9 and MemberTypeId = 1) 
and (isnull(@MyAge, 0) between isnull(MinAge, 0) and isnull(MaxAge, 200)) 
order by 
    t.MinAge desc, t.MaxAge desc 
; 

这让你有MINAGE = 38的记录不是空值。

+1

但是'(AssuranceId = 9和MemberTypeId = 1)'只应该返回任何与BETWEEN部分完全匹配的行。 – jarlh

+0

即使有_also_范围匹配记录,这将返回匹配“IS NULL”的记录。 –

0

有一个选择行,其中AssuranceId = 9和MemberTypeId = 1

随着其CTE,如果BETWEEN条件为真,则返回该行公用表表达式(CTE)。如果这样的行根本不存在,则为OR

with cte as 
(
    select * 
    from Mytable 
    where AssuranceId = 9 and MemberTypeId = 1 
) 
select * from cte 
where (isnull(@MyAge, 0) between isnull(MinAge, 0) and isnull(MaxAge, 200) 
     AND (MinAge is not null or MaxAge is not null)) 
    OR NOT EXISTS (select * from cte 
        where isnull(@MyAge, 0) between isnull(MinAge, 0) and isnull(MaxAge, 200) 
        and (MinAge is not null or MaxAge is not null)) 
+0

贾特 - 请记住,还有其他保证金额,所以查询必须是“保证和会员类型特定 –

+0

@BhekiNzuza,好吧,我不太确定只要年龄是正确的,我会编辑。 – jarlh

+0

谢谢 - 这很接近 - 但它返回65岁...不在哪里最小和最大年龄是空行.....对于那个具体的保证和memberType ...我会玩这个查询 –

0

试试这个..

select top (1) * -- you might be excepting only one row here by preference 
from Mytable 
where (AssuranceId = 9 and MemberTypeId = 1) 
and (-- added 
     (@MyAge between MinAge and MaxAge) -- first preference 
     OR(MinAge IS NULL AND MaxAge<[email protected]) --Second preference 
     OR(MaxAge IS NULL AND MinAge>[email protected]) -- third preference 
     OR(MinAge IS NULL AND MaxAge Is NUll) -- Last preference 
    )-- added 
+0

Moumit - 这返回一个错误的记录(错误的保证Id:1,membertypeId:3) 考虑到 - 还有其他保证和membertypes –

+0

当然确定..请检查我的更新 – Moumit

0

试试这个:

declare @MyAge int; 
select @MyAge = 21; 
select * from Mytable 
where (AssuranceId = 9 and MemberTypeId = 1) 
and (MinAge is NULL OR MinAge <= @MyAge) AND (MaxAge is NULL OR MaxAge >= @MyAge)