在SQL Server 2012中构建日期时间

dev*_*969 2 t-sql sql-server sql-server-2012

我需要datetime在另一个2列(datetime)的基础上构建一个select语句.

我似乎无法使转换正确.你能发现我做错了什么吗?在我看来,DatePart它忽略了当天的"0"部分

下面的脚本应该创建所需的所有数据

IF EXISTS (SELECT * FROM sys.databases WHERE name='TestDB')
BEGIN
    ALTER DATABASE TestDB 
    SET SINGLE_USER WITH ROLLBACK IMMEDIATE;

    DROP DATABASE TestDB
END

CREATE DATABASE TestDB
GO

IF OBJECT_ID(N'[dbo].[TestTable]','U') IS NOT NULL
   DROP TABLE [dbo].[TestTable]
GO

CREATE TABLE [dbo].[TestTable]
(
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [DateSample1] datetime NOT NULL,
    [DateSample2] datetime NOT NULL
)
GO

INSERT dbo.TestTable (DateSample1, DateSample2)
VALUES('2006-10-06 00:00:00.000', '2007-01-17 00:00:00.000')

/*
In your select statement you should return another column "DateSample3"
and this should be year from DateSample1 and month and day from dateSample2
*/
--my try1
SELECT 
    tt.DateSample1, tt.DateSample2,
    DateSample3 = CAST(DATEPART(YYYY, tt.DateSample1) AS CHAR(4)) 
            + CAST(DATEPART(MM, tt.DateSample2) AS CHAR(2)) 
            + CAST(DATEPART(dd, tt.DateSample2) AS CHAR(2))
        ,WantedResultForDateSample3='2006-01-17 00:00:00.000'
FROM 
    dbo.TestTable tt

--mytry2 THROWS AN ERROR
--Conversion failed when converting date and/or time from character string
/*
SELECT 
    tt.DateSample1, tt.DateSample2,
    DateSample3 = CONVERT(DATETIME,CAST(DATEPART(YYYY, tt.DateSample1) AS CHAR(4)) 
            + CAST(DATEPART(MM, tt.DateSample2) AS CHAR(2)) 
            + CAST(DATEPART(dd, tt.DateSample2) AS CHAR(2)),120),
    WantedResult='2006-01-17 00:00:00.000'
FROM 
    dbo.TestTable tt
*/
Run Code Online (Sandbox Code Playgroud)

Mar*_*ith 8

您可以使用 DATETIMEFROMPARTS

DATETIMEFROMPARTS(YEAR(tt.DateSample1),
                  MONTH(tt.DateSample2),
                  DAY(tt.DateSample2),
                  0,0,0,0)
Run Code Online (Sandbox Code Playgroud)

这比构建字符串IMO要简洁得多.

无论您使用哪种方法,您都可能需要根据此要求处理不可能的日期.一种方法如下

SELECT CASE WHEN month=2 
             AND day = 29 
             AND (yr % 4 != 0 OR (yr % 100 = 0 AND yr % 400 != 0))
            THEN NULL
            ELSE
            DATETIMEFROMPARTS(yr,
                              month,
                              day,
                              0,0,0,0)
             END
 FROM [dbo].[TestTable] tt
 CROSS APPLY (VALUES (YEAR(tt.DateSample1),
                     MONTH(tt.DateSample2),
                       DAY(tt.DateSample2))) V(yr, month, day)
Run Code Online (Sandbox Code Playgroud)

SQL小提琴