从时间戳创建动态记录

时间:2018-03-09 00:36:10

标签: sql sql-server

我有下表:

Date        Time                        Location    
2017-01-01  2017-01-01 13:00:00.000     Boston      --main record
2017-01-01  2017-01-01 14:00:00.000     Boston      --new record
2017-01-01  2017-01-01 15:00:00.000     Boston      --new record

2017-01-01  2017-01-01 13:00:00.000     Philly      --main record
2017-01-01  2017-01-01 14:00:00.000     Philly      --new record
2017-01-01  2017-01-01 15:00:00.000     Philly      --main record
2017-01-01  2017-01-01 16:00:00.000     Philly      --new record

我想在Time和(Time + leadHourDiff)之间动态创建小时记录

所以最终的结果是:

products = {"V14LC": "A", "V15LC": "A", "V20LC": "B", "V20LCACSPV": "B", "VPRC": "A", "V25LC": "B,I", "V28LC": "B,28,I"}

cases = {"case1": "BDH", "case5": "BCD", "case5c": "BCC", "case8D": "DD", "case8DC": "CDD", "case12": "CDH", "case14": "DEH", "case15": "CCDD"}

3 个答案:

答案 0 :(得分:1)

一个选项是使用数字表(可以使用递归cte生成)并将leadHourDiff列加入到该表中。

with numbers(num) as (select 0
                      union all
                      select num+1 from numbers where num < 100 --change this as needed
                     ) 
select t.*,dateadd(hour,n.num,t.datetime_col) as new_datetime
from tbl t
join numbers n on t.leadHourDiff >= n.num

答案 1 :(得分:1)

一种简单的方法是使用递归CTE:

with cte as (
      select id, date, time, Location, leadHourDiff
      from t
      union all
      select id, date, dateadd(hour, 1, time), location, leadHourDiff - 1
      from cte
      where leadHourDiff >= 0
     )
select date, time, Location
from cte
order by location, date, time;

答案 2 :(得分:0)

以下是我最终如何做到这一点。另外,忘了提到我只想要缺少时间值。这对我来说是一个tpyo。这是整个解决方案

CREATE TABLE #Orders(
    Id          int IDENTITY(1,1)
    ,[Time]     datetime
    ,[Location] varchar(20) 
    ,OrderAmt   int
)

INSERT INTO #Orders
SELECT '2017-01-01 11:00:00', 'Boston', 23  UNION ALL
SELECT '2017-01-01 12:00:00', 'Boston', 31  UNION ALL
SELECT '2017-01-01 13:00:00', 'Boston', 45  UNION ALL
SELECT '2017-01-01 16:00:00', 'Boston', 45  UNION ALL ---15
SELECT '2017-01-01 17:00:00', 'Boston', 67  UNION ALL
SELECT '2017-01-01 18:00:00', 'Boston', 89  UNION ALL
SELECT '2017-01-01 19:00:00', 'Boston', 90  UNION ALL
SELECT '2017-01-01 20:00:00', 'Boston', 123 UNION ALL
SELECT '2017-01-01 21:00:00', 'Boston', 145 UNION ALL
SELECT '2017-01-01 22:00:00', 'Boston', 156 UNION ALL
SELECT '2017-01-01 23:00:00', 'Boston', 145 UNION ALL
SELECT '2017-01-02 00:00:00', 'Boston', 167 UNION ALL

SELECT '2017-01-01 11:00:00', 'Philly', 23  UNION ALL
SELECT '2017-01-01 12:00:00', 'Philly', 31  UNION ALL
SELECT '2017-01-01 13:00:00', 'Philly', 45  UNION ALL
SELECT '2017-01-01 15:00:00', 'Philly', 45  UNION ALL
SELECT '2017-01-01 17:00:00', 'Philly', 67  UNION ALL
SELECT '2017-01-01 18:00:00', 'Philly', 89  UNION ALL
SELECT '2017-01-01 19:00:00', 'Philly', 90  UNION ALL
SELECT '2017-01-01 20:00:00', 'Philly', 123 UNION ALL
SELECT '2017-01-01 21:00:00', 'Philly', 145 UNION ALL
SELECT '2017-01-01 22:00:00', 'Philly', 156 UNION ALL
SELECT '2017-01-01 23:00:00', 'Philly', 145 UNION ALL
SELECT '2017-01-02 00:00:00', 'Philly', 167


;WITH HourDiff AS (                     
    SELECT *
    FROM
    (
        SELECT 
            Id
            ,CAST([Time] AS date) AS [Date]
            ,[Time]
            ,[Location] 
            ,COALESCE(lead(DATEPART(HOUR, [Time])) OVER(PARTITION BY [Location], CAST([Time] AS date) ORDER BY [Time] ASC ) - DATEPART(HOUR, [Time]),1)-1 AS leadHourDiff
        FROM #Orders    
    ) t1
    WHERE t1.leadHourDiff <> 0  
)
, CTE AS (

    SELECT 
        Location
        ,DATEADD(HOUR, leadHourDiff, [Time]) AS missingTime     
    FROM HourDiff

    UNION ALL

    SELECT 
        Location
        ,DATEADD(HOUR, leadHourDiff - 1, [Time]) AS missingTime     
    FROM HourDiff
    WHERE Time < DATEADD(HOUR, leadHourDiff - 1, [Time])
)

SELECT
    Location
    ,CAST(missingTime AS time) AS missingTime
FROM CTE
ORDER BY Location, missingTime

DROP TABLE #Orders

最终结果:

Location    missingTime
Boston      14:00:00.000
Boston      15:00:00.000
Philly      14:00:00.000
Philly      16:00:00.000

<强>更新

这是一个更新......当我为纽约添加新数据时,最终的CTE无法正常工作

纽约的新数据:

SELECT '2017-01-01 11:00:00', 'New York', 23    UNION ALL
SELECT '2017-01-01 20:00:00', 'New York', 31    UNION ALL

新的最终CTE:

, CTE AS (

    SELECT 
        Location
        ,DATEADD(HOUR, leadHourDiff, [Time]) AS missingTime
        ,[Time]     
        ,leadHourDiff
    FROM HourDiff

    UNION ALL

    SELECT 
        Location
        ,DATEADD(HOUR, leadHourDiff - 1 , [Time]) AS missingTime    
        ,[Time]     
        ,leadHourDiff - 1   
    FROM CTE
    WHERE leadHourDiff >= 0
    AND Time < DATEADD(HOUR, leadHourDiff - 1, [Time])  
)

最终结果:

Location    missingTime
Boston      14:00:00.0000000
Boston      15:00:00.0000000
New York    12:00:00.0000000
New York    13:00:00.0000000
New York    14:00:00.0000000
New York    15:00:00.0000000
New York    16:00:00.0000000
New York    17:00:00.0000000
New York    18:00:00.0000000
New York    19:00:00.0000000
Philly      14:00:00.0000000
Philly      16:00:00.0000000