Cast()为smalldatetime

时间:2016-04-11 17:14:35

标签: sql-server tsql sql-server-2008-r2

我正在尝试将datetime投射到smalldatetime,当某行的smalldatetime类型的日期值超出范围时,我想将日期设置为允许的最大日期的默认值,仍然可以进行比较。

SELECT Sum(Case When Cast(shph.datetoship as smalldatetime) < @day1datetoship Then shpd.ordered Else 0 End) as TotDemandPast
FROM shipments shph
WHERE shph.pending = 1;

因此当shph.datetoship2080-01-11 00:00:00.000时, 我希望将其更改为2079-06-06 00:00:00.000,然后与@day1datetoship进行比较。

有一种简单而优雅的方法吗?

更新

经过更多测试,这两个答案证明了一些问题。 最后,最后通过在Case中放置另一个Cast语句来解决问题。

最终守则:

SELECT Sum(Case When Cast(Case WHEN shph.datetoship > '2079-06-06 00:00:00' THEN '2079-06-06 00:00:00' Else shph.datetoship END as smalldatetime) < @day1datetoship Then shpd.ordered Else 0 End) as TotDemandPast
FROM shipments shph
WHERE shph.pending = 1;

2 个答案:

答案 0 :(得分:1)

DECLARE @shipments TABLE(
    datetoship DATETIME,
    pending BIT,
    ordered BIT
)

INSERT INTO @shipments SELECT '1899-01-01',1,1
INSERT INTO @shipments SELECT '1900-01-01',1,1
INSERT INTO @shipments SELECT '2079-06-06',1,1
INSERT INTO @shipments SELECT '2079-06-07',1,1

DECLARE @day1datetoship SMALLDATETIME='04/11/2016'

SELECT
    Sum(
        Case
            WHEN shph.datetoship>='1900-01-01' and shph.datetoship<='2079-06-06 23:59' THEN
                CASE
                    WHEN Cast(shph.datetoship as smalldatetime) < @day1datetoship then shph.ordered
                    Else 0
                END
            When '2079-06-06' < @day1datetoship Then shph.ordered
            Else 0
        End
    ) as TotDemandPast
FROM @shipments shph
WHERE shph.pending = 1;

答案 1 :(得分:1)

您可以尝试使用Try_Parse语法的查询。请注意,这在较新版本的SQL Server(2012及更高版本)中使用

SELECT 
  Sum(
      Case 
      When ISNULL(Try_parse(shph.datetoship as smalldatetime),'2079-06-06') < @day1datetoship 
      Then shpd.ordered 
      Else 0 
      End
      ) as TotDemandPast
FROM shipments shph 
WHERE shph.pending = 1;

对于较低版本的SQL Server,您可以使用以下查询

SELECT 
  Sum(
      Case 
      When 
       ( 
         shph.datetoship >='1900-01-01' AND 
         shph.datetoship <='2079-06-06' AND 
         CAST(shph.datetoship as smalldatetime) < @day1datetoship 
       ) OR 
       ('2079-06-06' < @day1datetoship )
      Then shpd.ordered 
      Else 0 
      End
      ) as TotDemandPast
FROM shipments shph 
WHERE shph.pending = 1;