Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL中自动基于时间值的增量日期_Sql Server_Tsql_Date_Datetime - Fatal编程技术网

Sql server SQL中自动基于时间值的增量日期

Sql server SQL中自动基于时间值的增量日期,sql-server,tsql,date,datetime,Sql Server,Tsql,Date,Datetime,我有一个客户机数据,它有一个候选id,一个开始日期,它只有一个varchar格式的日期和一个与该日期相关联的时间值 为了简要解释数据,考生将在一天中的任何时间点(例如2014年10月20日上午10:00)来到学习中心。开始日期为2014年10月20日,从上午10:00开始,他将根据时间点进行测试。因此,如果时间点是2小时,那么在下午12:00,他将进行测试。如果时间点是8小时,它将与上午10:00相加,并基于此,他将在下午6:00进行测试。当时间点达到00:00时,开始日期需要是下一个日期,而不

我有一个客户机数据,它有一个候选id,一个开始日期,它只有一个varchar格式的日期和一个与该日期相关联的时间值

为了简要解释数据,考生将在一天中的任何时间点(例如2014年10月20日上午10:00)来到学习中心。开始日期为2014年10月20日,从上午10:00开始,他将根据时间点进行测试。因此,如果时间点是2小时,那么在下午12:00,他将进行测试。如果时间点是8小时,它将与上午10:00相加,并基于此,他将在下午6:00进行测试。当时间点达到00:00时,开始日期需要是下一个日期,而不是2014年10月20日

开始日期需要附加时间值,这样当它跨越时间00:00时,开始日期需要在第二天增加1 ie。我使用下面的代码将开始日期添加到时间中

CASTSTARTDATE作为日期时间+CASTCASTSTUFF[TIME],3,0',:'作为时间0作为日期时间作为[EXPECTEDDATETIME]

然而,通过上面的代码,我已经创建了预期的日期时间

由于动态数据,我将无法硬编码该值。我尝试将>=和<应用于时间值,例如

case when MyTime >= '00:00' and MyTime < '08:10' the Dateadd(day, 1, date)

有人能帮我这个忙吗

首先,这看起来像是坏数据,可能应该首先使用正确的数据类型datetime正确插入

你可以使用一个按钮来做你想做的事情

为了处理您的数据集,我添加了一个Id列,用于对数据进行排序,因为您不能按日期和时间排序,因为您的数据存在每个候选分组重复日期的问题

可运行样本:

-- temp table to hold your data
CREATE TABLE #Temp
    (
      Id INT ,
      Candidate INT ,
      MyDate NVARCHAR(10) ,
      MyTime NVARCHAR(10)
    )

-- insert the dummy data (with added id for ordering)
INSERT  INTO #Temp
        ( Id, Candidate, MyDate, MyTime )
VALUES  ( 1, 1, '20141020', '1000' ),
        ( 2, 1, '20141020', '1200' ),
        ( 3, 1, '20141020', '1400' ),
        ( 4, 1, '20141020', '1800' ),
        ( 5, 1, '20141020', '0000' ),
        ( 6, 1, '20141020', '1200' ),
        ( 7, 1, '20141020', '1300' ),
        ( 8, 2, '20141020', '1100' ),
        ( 9, 2, '20141020', '1300' ),
        ( 10, 2, '20141020', '1500' ),
        ( 11, 2, '20141020', '1900' ),
        ( 12, 2, '20141020', '2100' ),
        ( 13, 2, '20141020', '2300' ),
        ( 14, 2, '20141020', '0230' ),
        ( 15, 2, '20141020', '1330' ),
        ( 16, 3, '20141026', '1530' ),
        ( 17, 3, '20141026', '2000' ),
        ( 18, 3, '20141026', '0930' ),
        ( 19, 3, '20141026', '1020' ),
        ( 20, 3, '20141026', '1120' )

-- insert data into new temp table, converting values to dates and times  
SELECT  Id ,
        Candidate ,
        CONVERT(DATE, MyDate) AS MyDate ,
        CONVERT(TIME, LEFT(MyTime, 2) + ':' + RIGHT(MyTime, 2)) AS MyTime
INTO    #TempFormatted
FROM    #Temp

-- recursive cte
;WITH    cte
          AS ( 
               -- take the first row
               SELECT   Id ,
                        Candidate ,
                        MyDate ,
                        MyTime
               FROM     #TempFormatted
               WHERE    Id = 1
               -- add next row (look at join: t.Id = cte.Id + 1)
               UNION ALL
               SELECT   t.Id ,
                        t.Candidate ,
                        -- CASE used to compare rows and add a DAY if required
                        CASE WHEN t.MyTime > cte.MyTime
                                  AND t.Candidate = cte.Candidate
                             THEN cte.MyDate
                             WHEN t.MyTime < cte.MyTime
                                  AND t.Candidate = cte.Candidate
                             THEN DATEADD(DAY, 1, t.MyDate)
                             ELSE t.MyDate
                        END AS MyDate ,
                        t.MyTime
               FROM     cte
                        INNER JOIN #TempFormatted t ON t.Id = cte.Id + 1
             )
    -- output from cte
    SELECT  cte.Id ,
            cte.Candidate ,
            cte.MyDate ,
            cte.MyTime ,
            CONVERT(DATETIME, cte.MyDate) + CONVERT(DATETIME, cte.MyTime) FormattedValue
    FROM    cte

-- tidy up
DROP TABLE #Temp
DROP TABLE #TempFormatted

问题还不清楚。为什么第五排会提前一天跳,而不是第一排?为什么Expected Date列的最后一行从10月26日到10月21日?除了矛盾和任意的数据更改之外,将0添加到日期不应该改变任何内容,您可以将这两个列解析为日期和时间,并将它们添加以获得日期时间。将日期和时间存储为字符串是一个非常糟糕的想法。您使用的是哪个SQL Server版本?在SQL Server 2012+中,解析要容易得多strings@ZoffDino-前6条记录属于候选人1。第一行时间为0000,即该候选人的第二天。所以日期从20增加到21。另外,请让我知道您不清楚的部分。@PanagiotisKanavos-我已经解析了日期和时间到日期时间,这就是我在预期日期时间中显示的内容。我唯一需要的是当每行的日期超过0000时,日期需要增加到下一天Hi Tanner,太棒了。。。你解决了我的问题。。。谢谢。。。我不知道为什么人们投票否决了我的帖子。。。要求是否不明确?
-- temp table to hold your data
CREATE TABLE #Temp
    (
      Id INT ,
      Candidate INT ,
      MyDate NVARCHAR(10) ,
      MyTime NVARCHAR(10)
    )

-- insert the dummy data (with added id for ordering)
INSERT  INTO #Temp
        ( Id, Candidate, MyDate, MyTime )
VALUES  ( 1, 1, '20141020', '1000' ),
        ( 2, 1, '20141020', '1200' ),
        ( 3, 1, '20141020', '1400' ),
        ( 4, 1, '20141020', '1800' ),
        ( 5, 1, '20141020', '0000' ),
        ( 6, 1, '20141020', '1200' ),
        ( 7, 1, '20141020', '1300' ),
        ( 8, 2, '20141020', '1100' ),
        ( 9, 2, '20141020', '1300' ),
        ( 10, 2, '20141020', '1500' ),
        ( 11, 2, '20141020', '1900' ),
        ( 12, 2, '20141020', '2100' ),
        ( 13, 2, '20141020', '2300' ),
        ( 14, 2, '20141020', '0230' ),
        ( 15, 2, '20141020', '1330' ),
        ( 16, 3, '20141026', '1530' ),
        ( 17, 3, '20141026', '2000' ),
        ( 18, 3, '20141026', '0930' ),
        ( 19, 3, '20141026', '1020' ),
        ( 20, 3, '20141026', '1120' )

-- insert data into new temp table, converting values to dates and times  
SELECT  Id ,
        Candidate ,
        CONVERT(DATE, MyDate) AS MyDate ,
        CONVERT(TIME, LEFT(MyTime, 2) + ':' + RIGHT(MyTime, 2)) AS MyTime
INTO    #TempFormatted
FROM    #Temp

-- recursive cte
;WITH    cte
          AS ( 
               -- take the first row
               SELECT   Id ,
                        Candidate ,
                        MyDate ,
                        MyTime
               FROM     #TempFormatted
               WHERE    Id = 1
               -- add next row (look at join: t.Id = cte.Id + 1)
               UNION ALL
               SELECT   t.Id ,
                        t.Candidate ,
                        -- CASE used to compare rows and add a DAY if required
                        CASE WHEN t.MyTime > cte.MyTime
                                  AND t.Candidate = cte.Candidate
                             THEN cte.MyDate
                             WHEN t.MyTime < cte.MyTime
                                  AND t.Candidate = cte.Candidate
                             THEN DATEADD(DAY, 1, t.MyDate)
                             ELSE t.MyDate
                        END AS MyDate ,
                        t.MyTime
               FROM     cte
                        INNER JOIN #TempFormatted t ON t.Id = cte.Id + 1
             )
    -- output from cte
    SELECT  cte.Id ,
            cte.Candidate ,
            cte.MyDate ,
            cte.MyTime ,
            CONVERT(DATETIME, cte.MyDate) + CONVERT(DATETIME, cte.MyTime) FormattedValue
    FROM    cte

-- tidy up
DROP TABLE #Temp
DROP TABLE #TempFormatted