0

我有一张桌子举行活动和日期:

 NAME  | DOB
 -------------------
 Adam  | 6/26/1999
 Barry | 7/18/2005
 Daniel| 1/18/1984

我有另一个表将日期范围定义为开始时间或结束时间,每个表都有一个描述性代码:

 CODE      | DATE
 ---------------------
 YearStart| 6/28/2013
 YearEnd  | 8/14/2013

我正在尝试编写 SQL 来查找在第二个表中描述的时间的开始和结束之间的所有 Birthdates。YearStart 总是在六月,YearEnd 总是在八月。我的想法是尝试:

 SELECT 
      u.Name
      CAST(MONTH(u.DOB) AS varchar) + '/' + CAST(DAY(u.DOB) AS varchar) as 'Birthdate',
      u.DOB as 'Birthday'
 FROM 
      Users u
 WHERE
      MONTH(DOB) = '7' OR
      (MONTH(DOB) = '6' AND DAY(DOB) >= DAY(SELECT d.Date FROM Dates d WHERE d.Code='YearStart')) OR
      (MONTH(DOB) = '8' AND DAY(DOB) <= DAY(SELECT d.Date FROM Dates d WHERE d.Code='YearEnd')))
 ORDER BY
      MONTH(DOB) ASC, DAY(DOB) ASC

但这并没有通过,我猜是因为不能保证内部 SELECT 语句只会返回一行,所以不能被解析为日期时间。我如何实际完成此查询?

4

3 回答 3

2

这看起来很奇怪,我仍然觉得我们缺少相关的要求,但请看以下内容。从您的描述来看,年份似乎无关紧要,并且您希望生日在给定的月份/日期之间。

SELECT 
    t1.Name, t1.DOB
FROM 
    t1
    JOIN t2 AS startDate ON (startDate.Code = 'YearStart')
    JOIN t2 AS endDate ON (endDate.Code = 'YearEnd')
WHERE 
    STUFF(CONVERT(varchar, t1.DOB, 112), 1, 4, '') BETWEEN 
        STUFF(CONVERT(varchar, startDate.[Date], 112), 1, 4, '')
        AND
        STUFF(CONVERT(varchar, endDate.[Date], 112), 1, 4, '')  
于 2013-07-16T17:06:36.067 回答
0

尝试使用 PIVOT 来获取同一行的年份,就像这样。这将只返回“鲍勃”

DECLARE @Names TABLE(
NAME VARCHAR(20),
DOB VARCHAR(10));

DECLARE @Dates TABLE(
CODE VARCHAR(20),
THEDATE VARCHAR(10));

INSERT @Names (NAME,DOB) VALUES ('Adam', '6/26/1999');
INSERT @Names (NAME,DOB) VALUES ('Daniel', '1/18/1984');
INSERT @Names (NAME,DOB) VALUES ('Bob', '7/1/2013');

INSERT @Dates (CODE,THEDATE) VALUES ('YearStart', '6/28/2013');
INSERT @Dates (CODE,THEDATE) VALUES ('YearEnd', '8/14/2013');

SELECT * FROM @Names;
SELECT * FROM @Dates;

SELECT n.*
FROM @Names AS n
INNER JOIN (
    SELECT
            1 AS YearTypeId 
          , [YearStart]
          , [YearEnd]      
    FROM    ( SELECT    [CODE]
                      , THEDATE
              FROM      @Dates
            ) p PIVOT ( MIN(THEDATE)
                        FOR [CODE] 
                          IN ([YearStart],[YearEnd])
                      ) AS pvt) AS y
ON 
    n.DOB >= y.YearStart 
    AND n.DOB <= y.YearEnd       
于 2013-07-16T17:14:17.567 回答
0

从您问题的最后一段开始,我假设 Dates 表每年都有一个 YearStart 和一个 YearEnd 行,对吗?如果是这样,您的 SQL 查询应该包括您感兴趣的年份。

此外,即使严格地说“日期”不是 SQL Server 的保留字(请参阅Transact SQL 的保留关键字),您也应避免使用此类列名,因为例如 ODBC 不允许使用它们。

但是要仅使用您已经提供的信息做某事,您可以执行以下操作来获取 Dates 中定义的最后一年的生日庆祝者(假设该年确实有 YearStart 和 YearEnd 条目):

SELECT DISTINCT <the rest as in your example>
 FROM  Users u
 WHERE u.DOB >= (SELECT max(d1.Date) FROM Dates d1 WHERE d1.Code = 'YearStart')
  AND  u.DOB <= (SELECT max(d2.Date) FROM Dates d2 WHERE d2.Code = 'YearEnd')
 ORDER BY u.DOB;

上面的查询(我没有测试过——这只是为了展示原理)和你的帖子之间的主要区别是我相信 datetime 类型(或者你在数据库中使用的任何变体)可以按预期工作. 我的意思是数据库引擎很清楚(嗯,应该是)两个完整日期中的哪一个是最早和最新的 - 您不必分别提取和比较它们的组件。

/老板

于 2013-07-16T17:40:56.007 回答