【问题标题】:How to search birthdate using sql query? [duplicate]如何使用sql查询搜索生日? [复制]
【发布时间】:2014-03-28 17:31:49
【问题描述】:

我想从我的 sql server 数据库表中搜索 出生日期。我得到的问题是 DOB 的年份会有所不同,并且会晚于当年。如果我想获得与 facebook 生日提醒相同的生日将在未来 7 天到来的客户列表。

我尝试将smalldatetime 转换为varchar 并使用带有'_' 通配符LIKE 语句。例如Convert(Char(10),DOB,103) LIKE "__/02/____'。但是,它给了我本月即将到来的 DOB 的客户列表。它还向我显示了那些生日在本月之前已经过去的数据。我只想要那些生日在接下来 7 天的数据。

我的应用程序是用 C# 开发的。如果可以使用DataTableDataView 获得适当的结果,请建议我。

【问题讨论】:

标签: c# sql sql-server


【解决方案1】:

使用基于日期的函数。

//pseudo code
Where Month(birthdate) = 7
and Day(birthdate) = 4

7 月 4 日出生的人会升起

【讨论】:

  • 这并不涉及 OP,而是将日期与特定的日期和月份相匹配。我们的想法是获取今天和从今天起 7 天之间的日期,因此您无法将其与特定的日期和/或月份相匹配。
【解决方案2】:

我不在我的开发机器上,所以这是未经测试的,但应该指向正确的方向。

SELECT *
FROM TABLE
WHERE MONTH(DOB) = MONTH(GETDATE()) AND 
(DAY(DOB) BETWEEN DAY(GETDATE()) AND 
DAY(DATEADD(dd, 7, GETDATE())))

请注意,GETDATE() 函数获取机器上当前时区的当前日期和时间。要使用 UTC 日期,请将 GETDATE() 替换为 GETUTCDATE()

【讨论】:

  • 这行不通,因为一旦跨越两个月,您将无法获得正确的数据。
  • @FarligOpptreden 好点。我没想到...
【解决方案3】:

尝试使用 DATEPARTDATEADDDATEDIFF 函数为您的查询创建 where 子句。下面的 WHERE 子句应该可以得到你想要的结果:

SELECT *
FROM [Table]
WHERE DATEADD(yy, DATEDIFF(yy, [DOB], GETDATE()) +
          CASE
              WHEN DATEPART(mm, GETDATE()) > 
                   DATEPART(mm, DATEADD(dd, 7, GETDATE())) 
               AND DATEPART(mm, GETDATE()) <> DATEPART(mm, [DOB])
                   THEN 1 
              ELSE 0
          END, [DOB]) 
      BETWEEN GETDATE() AND DATEADD(dd, 7, GETDATE())

该子句的作用是使用 DATEADDDATEDIFF 将 [DOB] 值移动到当前年份,并在今天和从今天起 7 天之间进行匹配。

编辑:修改了条款以适应不同年份的周期。

【讨论】:

  • 这似乎也错过了今天是 12 月 31 日并且客户的生日在 1 月的第一周即将到来的边缘情况? SqlFiddle(小提琴更新)
  • 忙于修改答案 - 刚刚测试过,你是对的。
【解决方案4】:

使用this method of date assembly,这应该可以工作:

选择 * 来自客户 其中 DATEADD(day, DAY(DOB) -1, DATEADD(月, MONTH(DOB) - 1, DATEADD(年, YEAR(CURRENT_TIMESTAMP) - 1900, 0))) 在 CURRENT_TIMESTAMP 和 DATEADD 之间(DD,7,CURRENT_TIMESTAMP);

.

编辑
上述方法在一年的变化中不起作用。 确实如此,虽然相当笨拙(使用@Today 测试场景,然后在完成后替换CURRENT_TIMESTAMP):

DECLARE @Today DATE = '31 Dec 2013';
select *
from Customers
CROSS JOIN
    (
        SELECT YEAR(@Today) AS yr
        UNION
        SELECT YEAR(DATEADD(d, 7, @Today))
    ) years
where 
    DATEADD(day, DAY(DOB) -1, 
           DATEADD(month, MONTH(DOB) - 1,
               DATEADD(year, years.yr - 1900, 0)))
    BETWEEN @Today AND DATEADD(DD, 7, @Today);

SqlFiddle here

如果我们接近年底,cross join 将在今年或今年和明年返回,如果年份相同,UNION 将确保只有一行。如果退回 2 年(即我们在 12 月下旬),那么 Between 将排除客户在今年 1 月早些时候发生的 DOB :P 必须有一个更优雅的解决方案,但是......

【讨论】:

  • 为什么不将 DOB 和今天之间的年份差异添加到 DOB 并根据我的答案中发布的那样进行匹配?我以前无数次使用过这种方法,它总是 100% 有效......
【解决方案5】:

使用 StuartLC 的示例作为基准。如何为每条记录建立 DOB,而不是实际年份,而是使用当前年份和明年。这样,您可以在两个日期的 7 天范围内获取 DateDiff - 它处理年份翻转并且其意图非常明确。

例子:

DECLARE @Today DATE = '31 Dec 2013';

SELECT *
FROM Customers
WHERE
      cast(
          cast(Month(DOB) AS varchar) + '/' +
          cast(Day(DOB) AS varchar) + '/' +
          cast(Year(@Today) AS varchar) AS Date) BETWEEN @Today AND dateadd(day, 7, @Today)
OR
        cast(
          cast(Month(DOB) AS varchar) + '/' +
          cast(Day(DOB) AS varchar) + '/' +
          cast(Year(@Today) + 1 AS varchar) AS Date) BETWEEN @Today AND dateadd(day, 7, @Today)

Sql Fiddle here

【讨论】:

    猜你喜欢
    • 2014-08-21
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    相关资源
    最近更新 更多