SQL Server:按最近的生日列出

时间:2014-02-14 16:47:38

标签: sql sql-server tsql

A - 列B [DateTime]

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

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)

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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

答案 2 :(得分: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()))

结果集

生日消失后,用户vicky将被过滤掉。

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

结果集按下一个人的生日订购

答案 3 :(得分: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)