SQL Server:使用补充数据填充临时表

时间:2013-11-13 11:06:41

标签: sql sql-server sql-server-2005

我目前有以下结果集:

WEEKDAY     INITIAL_MIN       ENDING_MIN
----------- ----------------- -----------------
7           0                 150 
7           360               480
7           980               1310
6           200               300

这个数据得到了工作日(从1到7)和不可用的工作时间(以分钟为单位,因此0表示00:00和1439表示23:59)和我无法更改其格式/数据类型由于数据库限制

我需要将每个工作日的补充数据插入到另一个表中,所以在这个例子中它将是:

WEEKDAY     INITIAL_MIN       ENDING_MIN
----------- ----------------- -----------------
7           151               359
7           481               979
7           1311              1439
6           0                 199
6           301               1439
5           0                 1439
4           0                 1439
3           0                 1439
2           0                 1439
1           0                 1439

我得到的限制:

  • 这是一个SQL Server 2005数据库
  • 我无法创建电视/标量功能(只是程序)

1 个答案:

答案 0 :(得分:0)

这是一种可能的解决方案(假设您的初始结果集是@tmp):

首先,我必须为最终的SELECT设置结果集:

当一天的第一个记录没有从0开始时,我添加一个INITIAL_MIN = -1,ENDING_MIN = -1的占位符记录。我的最终选择现在将找到占位符和当天第一行之间的范围。

INSERT INTO @tmp
SELECT WEEKDAY, -1, -1
FROM @tmp 
WHERE WEEKDAY NOT IN (SELECT WEEKDAY FROM @tmp WHERE INITIAL_MIN <= 0)

下一个查询计算出所有缺失的时间范围 - 它将它们存储在临时表中,因此如果它已经存在,则必须先将其删除。

IF OBJECT_ID('tempdb..#result') IS NOT NULL
    DROP TABLE #result

SELECT t1.WEEKDAY
    ,INITIAL_MIN = ISNULL(t1.ENDING_MIN+1, 0)
    ,ENDING_MIN = ISNULL(t2.INITIAL_MIN-1, 1439)
INTO #result
FROM (
    SELECT *
        ,rn = ROW_NUMBER() OVER (PARTITION BY WEEKDAY ORDER BY INITIAL_MIN DESC) 
    FROM @tmp t
    WHERE ENDING_MIN < 1439
) t1 
LEFT JOIN (
    SELECT *
        ,rn = ROW_NUMBER() OVER (PARTITION BY WEEKDAY ORDER BY INITIAL_MIN DESC) 
    FROM @tmp t
) t2 ON t1.WEEKDAY = t2.WEEKDAY AND t2.rn = t1.rn-1
ORDER BY WEEKDAY, INITIAL_MIN

添加原始结果中没有的日期:

DECLARE @wkday TINYINT = 1
WHILE @wkday <= 7
BEGIN
    IF NOT EXISTS(SELECT 1 FROM @tmp WHERE WEEKDAY = @wkday)
    INSERT INTO #result 
    VALUES( @wkday, 0, 1439)

    SET @wkday = @wkday + 1
END  

最后只需从临时表中选择数据

SELECT * FROM #result

输出:

WEEKDAY INITIAL_MIN ENDING_MIN
------- ----------- -----------
1       0           1439
2       0           1439
3       0           1439
4       0           1439
5       0           1439
6       0           199
6       301         1439
7       151         359
7       481         979
7       1311        1439