【问题标题】:Using table values in DATEDIFF function在 DATEDIFF 函数中使用表值
【发布时间】:2016-07-24 12:00:45
【问题描述】:

所以我正在学习 TSQL,并被分配了一个应用程序,该应用程序详细介绍了某个系列电影的内容。我想添加到成品中的一件事是 DATEDIFF,其中我有主要演员的出生日期和电影的首映日期,但想返回首映时演员的年龄。

我的问题是,如果表格中已经存在这些日期,我该如何指定日期?

表格示例如下。

债券

BondID   FirstName   LastName   Birthdate
1        Sean        Connery    8/25/1930
2        George      Lazenby    9/5/1939
3        Roger       Moore      10/14/1927
4        Timothy     Dalton     3/21/1946
5        Pierce      Brosnan    5/16/1953
6        Daniel      Craig      3/2/1968

电影

ID   BondID    FilmTitle             Premiere
1      1       Dr. No                1963-05-08
2      1       From Russia With Love 1974-04-08
3      1       Goldfinger            1964-12-22
4      1       Thunderball           1965-12-29 

这是我目前拥有的。

SELECT b.Birthdate, f.Premiere, b.FirstName, b.LastName, f.FilmTitle
FROM Bond b INNER JOIN FilmID  f ON b.BondID = f.BondID
WHERE b.BondID = 1

SELECT DATEDIFF(YEAR, GETDATE(), GETDATE())  AS "YearDif"
WHERE GETDATE() = Bond.Birthdate AND GETDATE() = f.Premiere

数据

     Birthdate  Premiere    FirstName LastName  FilmTitle
1    1930-08-25 1963-05-08  Sean      Connery   Dr. No
2    1930-08-25 1974-04-08  Sean      Connery   From Russia With Love
3    1930-08-25 1964-12-22  Sean      Connery   Goldfinger
4    1930-08-25 1965-12-29  Sean      Connery   Thunderball

我想添加一列,说明首映时演员的年龄...我想我知道那个...但是...

我知道 DATEDIFF 部分的第二部分不正确,但是如何告诉 DATEDIFF 从哪里获取日期值?

任何帮助都会很棒!

【问题讨论】:

  • 您可能需要阅读有关 GETDATE() 的信息。它返回当前系统时间。这意味着您的 DATEDIFF 将始终返回 0。我只是假设您没有与确切系统时间匹配的 Premiere Birthdate 值。在您的情况下,它将类似于 DATEDIFF(Year, Bond.Birthdate, f.Premiere )。需要注意的一件事是 DATEDIFF 计算跨越的阈值的数量。它不会告诉你距离那个日期有多少年。

标签: sql-server tsql date datediff


【解决方案1】:

您的查询:

SELECT DATEDIFF(YEAR, GETDATE(), GETDATE())  AS "YearDif"
WHERE GETDATE() = Bond.Birthdate AND GETDATE() = f.Premiere

无法满足您的需求。 GETDATE() 只会返回今天的日期,所以本质上,如果在您运行查询的那一刻生日和首映日期是今天,上述内容只会返回一行。

您需要做的是下面的查询部分:

样本数据:

IF OBJECT_ID('tempdb..#Bond') IS NOT NULL
DROP TABLE #Bond
CREATE TABLE #Bond
(BondID INT ,FirstName VARCHAR(20),LastName VARCHAR(20),Birthdate  DATE)

INSERT INTO #Bond
VALUES
 (1        ,'Sean'        ,'Connery'    ,'8/25/1930')
,(2        ,'George'      ,'Lazenby'    ,'9/5/1939')
,(3        ,'Roger'       ,'Moore'      ,'10/14/1927')
,(4        ,'Timothy'     ,'Dalton'     ,'3/21/1946')
,(5        ,'Pierce'      ,'Brosnan'    ,'5/16/1953')
,(6        ,'Daniel'      ,'Craig'      ,'3/2/1968')

IF OBJECT_ID('tempdb..#Film') IS NOT NULL
DROP TABLE #Film

CREATE TABLE #Film
(ID  INT , BondID  INT , FilmTitle       VARCHAR(50),      Premiere  DATE)
INSERT INTO #Film
VALUES (1    ,  1,'Dr. No'              ,'1963-05-08')
,(2    ,  1,'From Russia With Love','1974-04-08')
,(3    ,  1,'Goldfinger'           ,'1964-12-22')
,(4    ,  1,'Thunderball'          ,'1965-12-29')

查询:

    SELECT b.Birthdate, f.Premiere, b.FirstName, b.LastName, f.FilmTitle , DATEDIFF(YEAR, b.Birthdate, Premiere) AS AgeOfActor
FROM #Bond b INNER JOIN #Film  f ON b.BondID = f.BondID 

结果:

回应评论:

你总是可以计算天数,然后除以 365:

SELECT b.Birthdate, f.Premiere, b.FirstName, b.LastName, f.FilmTitle , DATEDIFF(day, b.Birthdate, Premiere)/365 AS AgeOfActor
FROM #Bond b INNER JOIN #Film  f ON b.BondID = f.BondID 

或者为了更准确,您可以在几秒钟内完成:P

SELECT b.Birthdate, f.Premiere, b.FirstName, b.LastName, f.FilmTitle ,  DATEDIFF(second, b.Birthdate, Premiere)/(365.25*24*60*60)   AS AgeOfActor
FROM #Bond b INNER JOIN #Film  f ON b.BondID = f.BondID 

【讨论】:

  • 这真的很接近,但演员的年龄并不总是正确的。看看“Dr. No”,他在首映时已经 32 岁了。 43 为“来自俄罗斯的爱”。这就是 DATEDIFF 面临的挑战
  • @SeanLange 你是对的,这始终是挑战,因为 GETDATE() 总是比较使用日期部分。但是请在我的回答中查看我对您的评论的回复。
  • @SeanLange 实际上,如果您查看秒计算,一旦四舍五入到 0 dp,它们更接近年份计算
【解决方案2】:

这样的事情可以在 SQL 中一步完成。无需将中间结果存储在任何地方以供以后传递。


您只需将表中的列值传递给函数调用,如下所示:

SELECT 
 b.Birthdate, f.Premiere, b.FirstName, b.LastName, f.FilmTitle,
 DATEDIFF(YEAR, b.Birthdate, f.Premiere) AS actor_age_at_premiere
FROM 
 Bond b 
 INNER JOIN FilmID f 
  ON b.BondID = f.BondID

假设演员在他/她出演的电影的首映日期之前出生(这是一个公平的假设),结果将是肯定的Integer

如果您想包括演员年龄,那么您的第三个参数将是GETDATE() 而不是Premiere 列:

DATEDIFF(Year, b.Birthdate, GETDATE()) AS actor_age_current

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多