在两个日期之间查找记录,如果未找到,则返回日期最小的记录。

3

我有一个像这样的表格

Name       DateOfBirth
--------------------------------
Ramesh     17/04/1983

Pavan      16/03/1980

Rakesh     18/03/1975

Nadeem     19/05/1974

Kalam      20/08/2973 

我正在编写一个存储过程,伪代码如下:

我将一个日期作为输入参数传递给这个存储过程

  1. 如果找到 @InputDate,则SP应返回记录
  2. 如果 @InputDate 小于表中最小日期,则应返回最小日期的记录
  3. 如果未找到 @InputDate 但它在列的最小值和最大值之间,则应返回其后面的记录

    • 是否可能用一条语句来写出逻辑?
    • 完成此任务的最优化方法

1
你使用哪个关系型数据库管理系统(RDBMS)? - Giorgos Betsos
任何数据库都可以。 - Moiz Syed
说到日期/时间,许多dbms远非符合ANSI SQL的标准... - jarlh
2个回答

2
我认为以下查询(在MySQL中)可以得到您想要的结果:

我认为以下查询(在MySQL中)可以得到您想要的结果:

SELECT Name, DateOfBirth
FROM mytable
WHERE DateOfBirth >= @mydate
ORDER BY DateOfBirth LIMIT 1

案例1,输入:

@mydate = '1972-03-16'

输出:

Name,   DateOfBirth
-------------------
Nadeem, 1974-05-19

案例2,输入:

@mydate = '1980-03-16'

输出:

Name,   DateOfBirth
-------------------
Pavan,  1980-03-16

第三种情况,输入:

@mydate = '1982-03-16'

输出:

Name,    DateOfBirth
-------------------
Ramesh,  1983-04-17

案例4,输入:

@mydate = '2982-03-16'

输出:

Name,    DateOfBirth
-------------------
No records returned

很好 - 这可以很容易地转换成其他变体的SQL。 - David Faber

0

可以的。首先,让我们看看如何获取您设置中具有最小和最大日期的记录:

最小值

select top 1 Name, DateOfBirth
from yourtable
order by DateOfBirth

Max:

select top 1 Name, DateOfBirth
from yourtable
order by DateOfBirth desc

这是获取匹配记录的方法:

select top 1 Name, DateOfBirth
from yourtable
where DateOfBirth = @InputDate

现在,让我们把所有东西整合到一个查询中:

select mymin.Name as myminName, mymin.DateOfBirth as myminDateOfBirth,
       mymax.Name as mymaxName, myMax.DateOfBirth as mymaxDateOfBirth,
       therecord.Name as therecordName, therecord.DateOfBirth as therecordDateOfBirth
from
(select top 1 Name, DateOfBirth
from yourtable
order by DateOfBirth) mymin
join
(select top 1 Name, DateOfBirth
from yourtable
order by DateOfBirth desc) mymax
on 1 = 1
left join yourtable therecord
on therecord.DateOfBirth = @InputDate

正如您所看到的,我们可以 select 所有可能的值。最后一步是修改选择以仅获取所需记录的 NameDateOfBirth。如果没有匹配项并且日期不小于最小日期而且不大于最大日期,则返回 null。为此,我们需要使用 case-when 语法,像这样:

select case (therecord.Name is null)
When 1 then (case mymin.DateOfBirth > @InputDate when 1 then mymin.Name
             else case mymax.DateOfBirth < @InputDate when 1 then mymax.Name else null end)
Else therecord.Name
End as Name,
case (therecord.Name is null)
When 1 then (case mymin.DateOfBirth > @InputDate when 1 then mymin.DateOfBirth
             else case mymax.DateOfBirth < @InputDate when 1 then mymax.DateOfBirth else null end)
Else therecord.DateOfBirth
End as DateOfBirth
from
(select top 1 Name, DateOfBirth
from yourtable
order by DateOfBirth) mymin
join
(select top 1 Name, DateOfBirth
from yourtable
order by DateOfBirth desc) mymax
on 1 = 1
left join yourtable therecord
on therecord.DateOfBirth = @InputDate

我假设您使用的是SQL Server。

警告:这段代码没有经过测试,如果有任何拼写错误,请告诉我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接