Sql Server - 如何获得最少的合格记录?

时间:2016-03-02 10:11:43

标签: sql sql-server tsql

enter image description here

如何根据我传递给查询的“年龄”获得最少的行数?

这个年龄不是表中minAge或maxage的一部分..

我的存储过程的例子

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 或任何建议将不胜感激

5 个答案:

答案 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 :(得分:0)

如果我理解正确,您的查询逻辑就是要保留@MyAgeMinAge之间的MaxAge所有记录,除非是那里没有记录,在这种情况下,您需要MinAgeMaxAge都是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

在这种情况下,子查询的惩罚应该很小,因为它没有相关性。

答案 2 :(得分:0)

有一个公用表表达式(cte),用于选择AssuranceId = 9和MemberTypeId = 1的行。

使用该cte,如果BETWEEN条件为真,则返回该行。 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))

答案 3 :(得分: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<=@MyAge) --Second preference
       OR( MaxAge IS NULL AND MinAge>=@MyAge) -- third preference
       OR(MinAge IS NULL AND MaxAge Is NUll) -- Last preference
   )-- added 

答案 4 :(得分:0)

Try this:

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)