2014-02-14 70 views
1

A - 列B [DateTime]SQL服务器:列表中最近的生日

需要列表中的用户在该表中,在最近的生日排序。已经生日的用户应该在列表末尾考虑下一年。

select B from A (order by/where)? 

表实例

USER  DATE 
MARCELO 1988-04-11 
RICARDO 1965-12-30 
WILSON 1977-02-20 
PABLO 1985-01-10 
JOHN  NULL 

预期结果

WILSON 20/02 (Month/Day) 
MARCELO 11/04 
RICARDO 30/12 
PABLO  10/01 
(JOHN NOT IN THE LIST) 
+2

请提供样本数据和预期的结果。 –

+0

我编辑了我的问题 – MarceloMadnezz

回答

1

测试数据

DECLARE @TABLE TABLE(Name VARCHAR(100),Dob DATETIME) 
INSERT INTO @TABLE VALUES 
('Mark', '19961017'),('Josh', '19801119'),('Sam', '19700709'), 
('Vicky', '19500210'),('Dom', '19890308'),('Paul', '19840401') 
,('Nick', NULL) 

查询

SELECT Name, CAST(MONTH(Dob) AS NVARCHAR(2)) 
       + '/' + CAST(DAY(Dob) AS NVARCHAR(2)) [Dob Month/Day] 
FROM @TABLE 
WHERE DATEPART(DAYOFYEAR,Dob) - DATEPART(DAYOFYEAR,GETDATE()) > 0 
ORDER BY ABS(DATEPART(DAYOFYEAR,Dob) - DATEPART(DAYOFYEAR,GETDATE())) 

结果集

用户玉萍将被过滤掉因为生日不见了。

╔══════╦═══════════════╗ 
║ Name ║ Dob Month/Day ║ 
╠══════╬═══════════════╣ 
║ Dom ║ 3/8   ║ 
║ Paul ║ 4/1   ║ 
║ Sam ║ 7/9   ║ 
║ Mark ║ 10/17   ║ 
║ Josh ║ 11/19   ║ 
╚══════╩═══════════════╝ 

结果集是通过谁的生日排序是未来

+0

工作顺利,谢谢了很多! – MarceloMadnezz

+0

很高兴帮助我进一步更新了我的答案,以您的预期结果集中显示的格式获得结果。 –

+2

所以当你在12/31运行这个时会发生什么? – granadaCoder

1
select name, birthdate 
from yourtable 
where birthdate is not null 
order by datepart(dy,dateadd(d,- DATEPART(dy, getdate()),birthdate)) 
+0

嗨podiluska,谢谢你的时间。我用预期的结果编辑了我的问题。你可以重做查询以适应这种情况? – MarceloMadnezz

+0

感谢您的时间,我们的朋友M.Ali代码工作顺利 – MarceloMadnezz

1

该解决方案: “缠绕” 了整整一年。 并且还允许“投射多少个月”过滤器。

IF OBJECT_ID('tempdb..#Employee') IS NOT NULL 
    begin 
      drop table #Employee 
    end 


    CREATE TABLE #Employee 
    ( 
    SurrogateKeyIDENTITY int not null IDENTITY (1,1) , 
    NameOf varchar(12) not null , 
    BirthDate datetime not null 
    ) 


    Insert into #Employee (NameOf, BirthDate) 

    Select 'A', '01/01/1999' 
    UNION ALL Select 'B', '01/16/1941' 
    UNION ALL Select 'C', '01/29/1965' 
    UNION ALL Select 'D', '02/13/1944' 
    UNION ALL Select 'P', '02/14/1978' 
    UNION ALL Select 'Q', '02/15/1984' 
    UNION ALL Select 'R', '03/13/1948' 
    UNION ALL Select 'S', '04/16/1983' 
    UNION ALL Select 'T', '05/17/1953' 
    UNION ALL Select 'U', '07/19/1959' 
    UNION ALL Select 'V', '08/16/1959' 
    UNION ALL Select 'W', '09/1/1959' 
    UNION ALL Select 'X', '10/30/1959' 
    UNION ALL Select 'Y', '11/16/1959' 
    UNION ALL Select 'Z', '12/31/1972' 


Declare @MyCURRENT_TIMESTAMP datetime 
/* select @MyCURRENT_TIMESTAMP = CURRENT_TIMESTAMP */ 
select @MyCURRENT_TIMESTAMP = '02/14/2014' 

Declare @NumberOfMonthsToGoOut int 
select @NumberOfMonthsToGoOut = 12 



;WITH myCalculationsCTE (NameOf, BirthDate, [NoYearBirthDate] , [NoYearCurrentDate]) 
AS 
(
    SELECT NameOf, BirthDate 
    , DATEFROMPARTS(1900 , MONTH(BirthDate), DAY (BirthDate)) [NoYearBirthDate] 
    , DATEFROMPARTS(1900 , MONTH(@MyCURRENT_TIMESTAMP), DAY (@MyCURRENT_TIMESTAMP)) [NoYearCurrentDate] 
    FROM #Employee 
    WHERE BirthDate IS NOT NULL 
) 
, 
myCTE (NameOf, BirthDate, [NoYearBirthDate] , [NoYearCurrentDate] , DerivedMonthDiff) 
AS 
(
    SELECT NameOf, BirthDate 
    , [NoYearBirthDate] 
    , [NoYearCurrentDate] 

    , [DerivedMonthDiff] = CASE 
     WHEN [NoYearBirthDate] >= [NoYearCurrentDate] 
      then DATEDIFF(m , [NoYearCurrentDate], [NoYearBirthDate]) 
     else 
      DATEDIFF(m , [NoYearCurrentDate], [NoYearBirthDate]) + 12 end 

    FROM myCalculationsCTE 
) 

SELECT NameOf, BirthDate , [NoYearBirthDate] , [NoYearCurrentDate] 
    , DerivedMonthDiff 
    , MONTH([NoYearBirthDate]) [Month] 
    , DAY ([NoYearBirthDate]) [DayOf] 

    FROM myCTE 
    where [DerivedMonthDiff] <= @NumberOfMonthsToGoOut 
    order by DerivedMonthDiff , MONTH([NoYearBirthDate]) , DAY ([NoYearBirthDate]) 

    IF OBJECT_ID('tempdb..#Employee') IS NOT NULL 
    begin 
      drop table #Employee 
    end 
+0

感谢您的时间,我们的朋友M.Ali代码工作顺利。 – MarceloMadnezz

+0

这是因为我在发布样本ddl和样本数据之前编写了它。 ... 情人节快乐。 – granadaCoder

+0

我已经修改了我的答案,以获得一整年的生日值,但是以相对于今天的日期(2014年2月14日为我的例子)的正确顺序 – granadaCoder

1
SELECT Name, CAST(MONTH(BIRTHDAY) AS NVARCHAR(2)) 
       + '/' + CAST(DAY(BIRTHDAY) AS NVARCHAR(2)) [Dob Month/Day],DATEPART(DAYOFYEAR,BIRTHDAY) as [dayofyear], 
       case when (DATEPART(DAYOFYEAR,BIRTHDAY) - DATEPART(DAYOFYEAR,GETDATE()) > 0) 
       THEN 
       DATEPART(DAYOFYEAR,BIRTHDAY) - DATEPART(DAYOFYEAR,GETDATE()) 
       ELSE 
       DATEPART(DAYOFYEAR,BIRTHDAY) + 365-DATEPART(DAYOFYEAR,GETDATE()) 
       END 
       AS [DAYSTILLBURTHDAY] 
FROM CONTACTS 
WHERE BIRTHDAY <> '9999-01-01 00:00:00.000' 
ORDER BY (case when (DATEPART(DAYOFYEAR,BIRTHDAY) - DATEPART(DAYOFYEAR,GETDATE()) > 0) 
       THEN 
       DATEPART(DAYOFYEAR,BIRTHDAY) - DATEPART(DAYOFYEAR,GETDATE()) 
       ELSE 
       DATEPART(DAYOFYEAR,BIRTHDAY) + 365-DATEPART(DAYOFYEAR,GETDATE()) 
       END) 
+0

[DAYSTILLBURTHDAY](这不是问题的一部分)的小偏移量,但是是一个正确和完整的列表。 – bummi