【问题标题】:Calculate the time between CreationDate and Now Date in SQL Server 2008在 SQL Server 2008 中计算 CreationDate 和 Now Date 之间的时间
【发布时间】:2013-11-13 23:38:55
【问题描述】:

在 facebook 中,在每个状态下,我都可以看到创建日期和现在日期之间的时间。前任。 1 小时前,6 个月前,1 年前,...

所以,在我的数据库 SQL 中,我想创建一个视图,其中包含一个描述 creationDate 和 NowDate 之间时间的列 - NVARCHAR(30) 可能包含字符串:1 天前、2 个月前等。

我有一个比较 2 DateTime 变量的解决方案,但不清楚:

  1. 我会将 DateCreation 和 Now 之间的时间计算为 TimeInterval
  2. 如果 TimeInterval “现在”,如果 TimeInterval >= 1 分钟且 计算 2 个时间点之间的分钟。假设 6 分钟 -> “6 分钟前”
  3. 类似地,持续数月或数年。

有没有其他解决方案。

【问题讨论】:

  • 您想以什么格式显示它?
  • 正是我想要的,列 (nvarchar):1 个月前、2 天前等
  • 我已经编辑了我的问题

标签: sql sql-server sql-server-2008


【解决方案1】:

您可以使用类似于以下的代码来生成数据。几个月的时间不是很精确,因为我一个月用了 30 天。多年来,我每年使用 365 天。但我想这应该足够精确。

declare @date1 as datetime = '20131103 13:00:40'
declare @date2 as datetime = '20160208 16:40:45'

select case 
    when datediff(ss, @date1, @date2) < 60 THEN cast(datediff(ss, @date1, @date2) as varchar(max)) + ' seconds ago'
    when datediff(ss, @date1, @date2) < 3600 THEN cast((datediff(ss, @date1, @date2) / 60) as varchar(max)) + ' minutes ago'
    when datediff(ss, @date1, @date2) < 86400 THEN cast((datediff(ss, @date1, @date2) / 3600) as varchar(max)) + ' hours ago'
    when datediff(ss, @date1, @date2) < 2592000 THEN cast((datediff(ss, @date1, @date2) / 86400) as varchar(max)) + ' days ago'
    when datediff(ss, @date1, @date2) < 31536000 THEN cast((datediff(ss, @date1, @date2) / 2592000) as varchar(max)) + ' months ago'
    else cast((datediff(ss, @date1, @date2) / 31536000) as varchar(max)) + ' years ago'
end

查询中的数字来自秒数:

  • 分钟 = 60
  • 小时 = 3600
  • 天 = 86400
  • 月 = 2592000
  • 年 = 31536000

不只使用几秒钟的更简单的版本是:

declare @date1 as datetime = '20131003 13:00:40'
declare @date2 as datetime = '20151101 16:40:45'

select case 
    when datediff(ss, @date1, @date2) < 60 THEN cast(datediff(ss, @date1, @date2) as varchar(max)) + ' seconds ago'
    when datediff(mi, @date1, @date2) < 60 THEN cast((datediff(mi, @date1, @date2)) as varchar(max)) + ' minutes ago'
    when datediff(hh, @date1, @date2) < 24 THEN cast((datediff(hh, @date1, @date2)) as varchar(max)) + ' hours ago'
    when datediff(dd, @date1, @date2) < 30 THEN cast((datediff(dd, @date1, @date2)) as varchar(max)) + ' days ago'
    when datediff(mm, @date1, @date2) < 13 THEN cast((datediff(mm, @date1, @date2)) as varchar(max)) + ' months ago'
    else cast((datediff(yy, @date1, @date2)) as varchar(max)) + ' years ago'
end

【讨论】:

  • 我认为月份是30天还是31天,您有什么建议吗?
  • 我认为这并不重要,因为没有人会期望精确到几个月。一个月平均有 30.4 天,因此接近 30 天。
  • 我的系统是为决策者设计的,他/她关心资产负债表的确切月份或年份。无论如何,谢谢你的帮助。
【解决方案2】:

我会把它放在一个类似的函数中:

 create function dbo.TimeDiffToWords(@eventDateTime as DateTime)
    returns varchar(100)
    as 
    begin
    declare @ret varchar(100)
    declare @value int
    declare @done bit

set @done = 0

set @value = datediff(year, @eventDateTime, getdate())

if @value > 0
begin
    set @ret = 'Over '+cast(@value as varchar(6))+' year(s) ago.'
    set @done = 1
end

if @done = 0
begin
  set @value = datediff(month, @eventDateTime, getdate())
    if @value > 0
    begin
        set @ret = 'Over '+cast(@value as varchar(6))+' months(s) ago.'
        set @done = 1
    end
end

if @done = 0
begin
  set @value = datediff(day, @eventDateTime, getdate())
    if @value > 0
    begin
        set @ret = 'Over '+cast(@value as varchar(6))+' days(s) ago.'
        set @done = 1
    end
end

-- continue till down to seconds ago.
if @done = 0
begin
    set @ret = 'Not coded yet.'
end

return @ret

end

那么你可以像下面的测试代码那样调用它:

select dbo.TimeDiffToWords(EventDateTime)
from (select dateadd(month,-40, getdate()) as EventDateTime
    union all select dateadd(day,-40, getdate())
    union all select dateadd(day,-6, getdate())
    union all select dateadd(day,-2, getdate())
    union all select dateadd(hour,-4, getdate())
    union all select dateadd(minute,-2, getdate())
) as testTimes

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 2015-12-09
    • 2012-04-14
    • 2020-06-30
    相关资源
    最近更新 更多