【问题标题】:How to get 30 days from now from SQL table如何从 SQL 表中获取从现在开始的 30 天
【发布时间】:2013-10-26 20:00:29
【问题描述】:

我正在使用 c# 和 sql 在 MVC4 中做我的项目。我有一个表 MemberDetails 包含表

CREATE TABLE [dbo].[MemberDetails] (
[Id]          INT           IDENTITY (1, 1) NOT NULL,
[Mem_FirstNA] VARCHAR (100) NOT NULL,
[Mem_LastNA]  VARCHAR (100) NOT NULL,
[Mem_Occ]     VARCHAR (100) NOT NULL,
[Mem_DOB]     DATETIME      NOT NULL,
[Mem_Email]   VARCHAR (50)  NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
 );

我只想选择未来 30 天内谁的生日的姓名和出生日期,我使用以下查询

SELECT 
    Mem_FirstNA, Mem_LastNA, Mem_DOB 
FROM 
    MemberDetails 
WHERE 
    Mem_DOB >= getdate() - 1 AND Mem_DOB <= getdate() + 30

对吗,我选择了 0 个项目,我使用下表。

 1  Pal Software    08-03-1987 AM 12:00:00
 3  mn  Par Bussiness   19-10-1967 AM 12:00:00
 4  man George  Business    13-11-1956 AM 12:00:00
 5  Smi Kan Housewife   22-10-1980 AM 12:00:00

【问题讨论】:

  • 您是否正在编写 SQL(结构化查询语言)并且真的是指 Microsoft SQL Server(实际产品)?如果是:请添加sql-server 标签以明确这一点。如果不是:什么这是用于数据库系统的?
  • 我知道这是一个古老的问题,但每个人都错过了一个关键点:Mem_DOB 包含 1900 年代的日期,然后人们想检查Mem_DOB &gt;= getdate()!上个世纪的日期永远不会大于今天的日期。

标签: sql sql-server-2008


【解决方案1】:

试试这个

SELECT 
    Mem_FirstNA, Mem_LastNA, Mem_DOB 
FROM 
    MemberDetails 
WHERE 
    WHERE DATEPART(mm,Mem_DOB) BETWEEN DATEPART(mm,getDate()) AND DATEPART(mm,getDate())+1;

【讨论】:

  • 阿加瓦尔:我仍然选择了 0 行
  • 我认为这行不通。您将不得不考虑当前年份。
  • @AmitAgrawal:我的数据库和查询中是否有任何日期格式问题
  • 在查询编辑器中运行查询,然后告诉我输出是什么。
  • @AmitAgrawal - Mem_DOB 是过去,getdate() 是今天。他们将如何平等?示例:说 dob 18-Oct-1980,它将如何与 dateadd(day, -n, getdate()) 匹配?因为getdate() 会返回2013
【解决方案2】:

更新

SELECT 
    Mem_FirstNA, Mem_LastNA, Mem_DOB 
FROM 
    MemberDetails 
WHERE 
    DATEDIFF(DAY, GETDATE(), DATEADD(YEAR, DATEDIFF(YEAR, Mem_DOB, GETDATE()), Mem_DOB)) BETWEEN 0 AND 30

【讨论】:

  • 我认为这个查询不会起作用。 Mem_DOB 是过去,getdate() 是今天。他们将如何平等?示例:说 dob 18-Oct-1980,它将如何与 dateadd(day, -n, getdate()) 匹配?因为getdate() 会返回2013
  • @unlimit,你是对的。我忘记将当前年份设置为出生日期
【解决方案3】:

为什么不用这个 where 子句:

WHERE MEM_DOB BETWEEN GETDATE()-1 AND GETDATE()+30

【讨论】:

【解决方案4】:

试试这个... 选择 Mem_FirstNA、Mem_LastNA、Mem_DOB 从 会员详情 在哪里 ltrim(str(year(GETDATE()))) + '-' + ltrim(str(month(Mem_DOB))) + '-' + ltrim(str(day(Mem_DOB))) >= getdate() - 1 AND ltrim(str(year(GETDATE()))) + '-' + ltrim(str(month(Mem_DOB))) + '-' + ltrim(str(day(Mem_DOB)))

编辑:此答案的 cmets 正确地指出,如果当前年份是闰年,它将不起作用。所以这次更新。使用Get a list of dates between two dates using a function可以更高效地生成日期列表

Select Mem_FirstNA, Mem_LastNA, Mem_DOB from MemberDetails m, (
Select datepart(dd,getdate()) as d,  datepart(mm,getdate()) as m
union
Select datepart(dd,getdate() + 1) as d,  datepart(mm,getdate() + 1) as m
union
Select datepart(dd,getdate() + 2) as d,  datepart(mm,getdate() + 2) as m
union
Select datepart(dd,getdate() + 3) as d,  datepart(mm,getdate() + 3) as m
union
Select datepart(dd,getdate() + 4) as d,  datepart(mm,getdate() + 4) as m
union
Select datepart(dd,getdate() + 5) as d,  datepart(mm,getdate() + 5) as m
union
Select datepart(dd,getdate() + 6) as d,  datepart(mm,getdate() + 6) as m
union
Select datepart(dd,getdate() + 7) as d,  datepart(mm,getdate() + 7) as m
union
Select datepart(dd,getdate() + 8) as d,  datepart(mm,getdate() + 8) as m
union
Select datepart(dd,getdate() + 9) as d,  datepart(mm,getdate() + 9) as m
union
Select datepart(dd,getdate() + 10) as d,  datepart(mm,getdate() + 10) as m
union
Select datepart(dd,getdate() + 11) as d,  datepart(mm,getdate() + 11) as m
union
Select datepart(dd,getdate() + 12) as d,  datepart(mm,getdate() + 12) as m
union
Select datepart(dd,getdate() + 13) as d,  datepart(mm,getdate() + 13) as m
union
Select datepart(dd,getdate() + 14) as d,  datepart(mm,getdate() + 14) as m
union
Select datepart(dd,getdate() + 15) as d,  datepart(mm,getdate() + 15) as m
)X
where   
datepart(dd, m.Mem_DOB) = x.d and datepart(mm, m.Mem_DOB) = x.m

如果您反对,请评论原因。

【讨论】:

  • 很好,但要考虑效率。我还没有测试过它的效率。
  • 你这个查询是在一月的日期
  • 这是错误的方法。如果您发现自己将日期转换为字符串,那么您做错了什么。这是进行转换的最慢方法,并且由于可能存在不同的数据库排序规则/操作系统日期格式,这是一种在流程中引入错误的方法。
  • @JoelCoehoorn - 我知道,这就是为什么我在评论中特别提到我没有测试它的效率。但在那一刻,这就是我想到的,因为这个答案是公认的,我将用一个有效的查询来更新答案。
  • 即使暂时忽略效率和格式,当尝试将闰日生日更新为普通(非闰)年时,此技术也会失败。
【解决方案5】:

应该可以。根据 cmets 删除了使用之间。 也适用于 1 月的出生日期

DECLARE @now DATETIME
    SET @now = GETDATE()

 SELECT Mem_FirstNA, Mem_LastNA, Mem_DOB
   FROM MemberDetails
  WHERE 
   CASE WHEN month(Mem_DOB) = 1
   THEN DATEADD(YY, YEAR(DATEADD(DAY, 30, DATEADD(m,  month(@now) - 1, DAY(@now) - 1))) - 1900, DATEADD(m,  month(Mem_DOB) - 1, DAY(Mem_DOB) - 1))
   ELSE DATEADD(m,  month(Mem_DOB) - 1, DAY(Mem_DOB) - 1)
    END
      > DATEADD(m,  month(@now) - 1, DAY(@now) - 1) 
    AND 
   CASE WHEN month(Mem_DOB) = 1
   THEN DATEADD(YY, YEAR(DATEADD(DAY, 30, DATEADD(m,  month(@now) - 1, DAY(@now) - 1))) - 1900, DATEADD(m,  month(Mem_DOB) - 1, DAY(Mem_DOB) - 1))
   ELSE DATEADD(m,  month(Mem_DOB) - 1, DAY(Mem_DOB) - 1)
    END
      < DATEADD(DAY, 30, DATEADD(m,  month(@now) - 1, DAY(@now) - 1))

希望对你有帮助

【讨论】:

  • 呃,请不要将BETWEEN 与日期/时间类型一起使用,especially on SQL Server。就个人而言,BETWEEN 应该从所有语句(和标准)中删除...
【解决方案6】:

试试这个

        SELECT 
           Mem_FirstNA, Mem_LastNA, Mem_DOB
        FROM 
             MemberDetails 
       WHERE DAYOFYEAR(Mem_DOB)-DAYOFYEAR(getdate())<=30

【讨论】:

  • DAYOFYEAR?不错,没想到。
  • 在年份边界处失败。如果 DOB := '1990-01-01' 和 getdate() == '2013-12-31' 会发生什么? (不过,我很匆忙地给了你 +1,所以尽情享受吧!:))
【解决方案7】:
SELECT 
    Mem_FirstNA, Mem_LastNA, Mem_DOB 
FROM 
    MemberDetails 
WHERE 
    Mem_DOB >= Cast(current_timestamp As Date) AND Mem_DOB < DATEADD(d, 30, Cast(current_timestamp As Date));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多