2012-04-26 13 views
0

私は、停止を記述するテーブルで行を取り出し、別のテーブルに挿入して記述するために計算時間範囲で分割しますそれぞれの所与の範囲内の1時間ごとの時間帯。ストアドプロシージャから一時テーブル内のIDを経由して行を更新する必要があります

以下のコード私たちに次のような出力が得られます。

私たちは、この行(元データ)から行ってきました!私はストアドプロシージャ(これは所望の出力ISを実行した後、これに

OutageDate  StartTime     EndTime    Duration 
2010-11-10 16:00:00.0000000 17:30:00.0000000 90 

私はちょうど)テーブルに保存する方法を知っておく必要があります。

OutageDate StartHour StartMinutes EndHour EndMinutes StartTime  EndTime  Duration 
2010-11-10 16 0  17  0  16:00:00.0000000  17:30:00.0000000 90 
2010-11-10 17 30  18  0  16:00:00.0000000  17:30:00.0000000 90 

次私は私がしたい時間値を越え、私の行を分割後のテーブルに保存する方法を把握する必要があるコードです。これが起こることを持っている理由、それはちょうどこの形式でそれらによって私よりも誰かによって要求ごとのようにする必要があると指定した上で、私はコントロールを持っていない:

--First, let's look at the original data in the table...just one row will do 

SELECT TOP (1) * 
    FROM actualTable 
    ORDER BY OutageDate ASC 

--Begin sproc logic 
declare @OutageDate date 
declare @StartTime time(7) 
declare @EndTime time(7) 
declare @StartHour bigint 
declare @EndHour int 
declare @StartMinute int 
declare @EndMinute int 
declare @Duration int 

declare @Temp_StartTime time 
declare @Temp_EndTime time 
declare @temp_StartHour int 
declare @temp_EndHour int 
declare @temp_StartMinute int 
declare @temp_EndMinute int 


SELECT TOP(1) @OutageDate = OutageDate, @StartTime = StartTime, @EndTime = EndTime, @Duration = Duration FROM actualTable 


SET @[email protected] 
SET @[email protected] 
SET @temp_StartHour=DATEPART(HOUR, @StartTime) 
SET @temp_EndHour=DATEPART(HOUR, @EndTime) 
SET @temp_StartMinute=DATEPART(MI, @StartTime) 
SET @temp_EndMinute=DATEPART(MI, @EndTime) 

PRINT @temp_StartHour 
PRINT @temp_EndHour 
PRINT @temp_StartMinute 
PRINT @StartTime 
PRINT @EndTime 

if(@temp_EndMinute>0) 
    BEGIN 
     SET @[email protected]_EndHour+1 
    END 

--this declares the temp table 

DECLARE @Temp_Table TABLE 
(
OutageDate date, 
StartHour int, 
StartMinute int, 
EndHour int, 
EndMinute int, 
StartTime time, 
EndTime time, 
Duration int 
) 

--Here's the loop that inserts the rows 

While((@[email protected]_StartHour>1)) 
    BEGIN 
     INSERT INTO @Temp_Table 
     SELECT 
      @OutageDate AS OutageDate, 
      (DATEPART(HOUR, @Temp_StartTime)) AS StartHour, 
      (DATEPART(MINUTE, @Temp_StartTime)) AS StartMinute, 
      @temp_StartHour+1 AS EndHour, 
      0 AS EndMinute, 
      @StartTime as StartTime, 
      @EndTime as EndTime, 
      @Duration AS Duration 


--DATEADD returns a specified date with the specified number interval (signed integer) added to a specified datepart of that date. 

     SET @[email protected]_StartHour+1 
     SET @Temp_StartTime=DATEADD(HOUR,1,@Temp_StartTime) 

--Let's make sure we account for the minutes in the first and last hours if any 

     if(DATEPART(MI, @Temp_StartTime)!=0) 
      BEGIN 
       SET @Temp_StartTime=DATEADD(MI,[email protected]_StartMinute,@Temp_StartTime) 
      END 
    END 

--Ok, if we're at the last row insertion, we still need the minutes the outage finished at...those go into StartMinutes 

    WHile((@[email protected]_StartHour=1)) 
    BEGIN 
     INSERT INTO @Temp_Table 
     SELECT 
     @OutageDate AS OutageDate, 
     (DATEPART(HOUR, @Temp_StartTime)) AS StartHour, 
     @temp_EndMinute AS StartMinute, 
     @temp_StartHour+1 AS EndHour, 
     0 AS EndMinute, 
     @StartTime as StartTime, 
     @EndTime as EndTime, 
     @Duration AS Duration 

--DATEADD returns a specified date with the specified number interval (signed integer) added to a specified datepart of that date. 

     SET @[email protected]_StartHour+1 
     SET @Temp_StartTime=DATEADD(HOUR,1,@Temp_StartTime) 

--Let's make sure we account for the minutes in the first and last hours if any 

     if(DATEPART(MI, @Temp_StartTime)!=0) 
      BEGIN 
       SET @Temp_StartTime=DATEADD(MI,[email protected]_StartMinute,@Temp_StartTime) 
      END 
    END 

--Need to add logic that drops and recreates the table from the temp table so we don't have to employ a cursor 

SELECT * FROM @Temp_Table 

BEGIN 
SELECT * INTO newTable FROM @Temp_Table 
END 

YOUがSMSでこのSTRAIGHTを実行する場合、 「は、その最も基本的で論理を得るでしょう:

declare @StartTime time 
declare @EndTime time 
declare @Temp_StartTime time 

declare @temp_StartHour int 
declare @temp_EndHour int 
declare @temp_StartMinute int 
declare @temp_EndMinute int 

SET @StartTime='2:30:00' 
SET @EndTime='4:01:00' 
SET @[email protected] 

SET @temp_StartHour=DATEPART(HOUR, @StartTime) 
SET @temp_EndHour=DATEPART(HOUR, @EndTime) 
SET @temp_StartMinute=DATEPART(MI, @StartTime) 
SET @temp_EndMinute=DATEPART(MI, @EndTime) 

if(@temp_EndMinute>0) 
    BEGIN 
     SET @[email protected]_EndHour+1 
    END 

DECLARE @Temp_Table TABLE 
(
    StartHour int, 
    StartMinute int, 
    EndHour int, 
    EndMinute int, 
    StartTime time, 
    EndTime time 
) 

WHile((@[email protected]_StartHour>=1)) 
    BEGIN 
     INSERT INTO @Temp_Table 
     SELECT (DATEPART(HOUR, @Temp_StartTime)) AS StartHour,(DATEPART(MINUTE, @Temp_StartTime)) AS StartMinute, 
     @temp_StartHour+1 AS EndHour, 
     0 AS EndMinute, @StartTime as StartTime, @EndTime as EndTime 

     SET @[email protected]_StartHour+1 
     SET @Temp_StartTime=DATEADD(HOUR,1,@Temp_StartTime) 

     if(DATEPART(MI, @Temp_StartTime)!=0) 
      BEGIN 
       SET @Temp_StartTime=DATEADD(MI,[email protected]_StartMinute,@Temp_StartTime) 
      END 
    END 

SELECT * FROM @Temp_Table 
+0

リバースあなたのコードは非常に時間がかかることになるだろうエンジニアリング。私たちに動作しないクエリを与えるのではなく、 'actualTable'にいくつかのソース行を表示し、それらが出力先でどの行を生成するのでしょうか?私は[あなたの他の質問]で述べたように(http://stackoverflow.com/questions/10338436/how-to-convert-a-datepart-hour-thats-military-time-for-midnight-00-to-a-a-価値観)、私は本当にあなたが上で使用しているロジックがはるかに複雑であると信じています。しかし、私がソースデータを見ることができないのか、そこから抜け出そうとしているのかは分かりません。 –

+0

Ok ...これを編集してみましょう。ありがとう。 – Lynn

+0

開始時刻が22:15で終了時刻が00:30だった行をサンプルデータ(明らかに望ましい結果)に追加することができます。開始日と終了時刻が異なる日に発生したときにどのような出力が予想されるかを理解できます? –

答えて

1

はまず、いくつかのセットアップ:今

USE tempdb; 
GO 

CREATE TABLE dbo.Outages 
(
    OutageDate DATE, 
    StartTime TIME(7), 
    EndTime TIME(7), 
    Duration INT 
); 

INSERT dbo.Outages SELECT '20101110', '16:00', '17:30', 90; 
/* 
-- I also tested these cases, and *think* it still produces what you expect: 
INSERT dbo.Outages SELECT '20101111', '13:00', '14:02', 62; 
INSERT dbo.Outages SELECT '20101112', '17:00', '18:00', 60; 
INSERT dbo.Outages SELECT '20101113', '16:05', '16:25', 20; 
INSERT dbo.Outages SELECT '20101114', '16:59', '18:01', 62; 
INSERT dbo.Outages SELECT '20101115', '22:15', '01:30', 165; 
*/ 

、クエリ:

例えば
;WITH n(n) AS 
(
    SELECT TOP 24 ROW_NUMBER() OVER (ORDER BY [object_id]) 
    FROM sys.objects 
), 
x AS 
(
    SELECT 
    o.OutageDate, StartHour = (DATEPART(HOUR, StartTime) + n.n - 1) % 24, 
    StartTime, EndTime, Duration, 
    rn = ROW_NUMBER() OVER (PARTITION BY o.OutageDate, o.StartTime ORDER BY n.n) 
    FROM n INNER JOIN dbo.Outages AS o 
    ON n.n <= CEILING(DATEDIFF(MINUTE, CONVERT(DATETIME, StartTime), 
    DATEADD(DAY, CASE WHEN EndTime < StartTime THEN 1 ELSE 0 END, 
    CONVERT(DATETIME, EndTime)))/60.0) 
), 
mx AS (SELECT OutageDate, StartTime, minrn = MIN(rn), maxrn = MAX(rn) 
    FROM x GROUP BY OutageDate, StartTime) 

-- insert into some other table 
SELECT 
    x.OutageDate, 
    x.StartHour, 
    StartMinutes = CASE 
     WHEN x.rn = mx.minrn THEN DATEPART(MINUTE, x.StartTime) ELSE 0 END, 
    EndHour = x.StartHour + 1, 
    EndMinutes = CASE 
     WHEN x.rn = mx.maxrn THEN DATEPART(MINUTE, x.EndTime) ELSE 0 END, 
    x.StartTime, 
    x.EndTime, 
    x.Duration 
FROM x INNER JOIN mx 
ON x.OutageDate = mx.OutageDate 
AND x.StartTime = mx.StartTime 
ORDER BY x.OutageDate, x.rn; 
GO 

あなたはそれが実際に挿入して

-- insert into some other table 

を交換、その後、さまざまなシナリオのためにあなたの右の行を与えていることを満足しています、例えば

INSERT dbo.OtherTable(col1, col2, ...) 

あなたはINTO句で

FROM x INNER JOIN mx 

を交換、その後、この出力からブランドの新しいテーブルを作成しようとしている場合は、

INTO dbo.MyNewTable FROM x INNER JOIN mx 

は、クリーンアップすることを忘れないでください:

DROP TABLE dbo.Outages; 
+0

私は何とか時間アウトのための全体のロジックで水を混乱させたので、下部からコードブロックで再投稿してくださいねえ、それはかなりいいですね。私は時間計算の上で私の論理を本当にうまくやり直すと思います。スーパー!また、これを先の一時テーブルに保存します。私はあなたの指示で残りのドットをうまく接続できると思います。 7年後にTSQLを再訪した今日は、クラッシュコースとなっています。 – Lynn

+0

また、問題を報告してくれてありがとうございました。非常に高く評価。申し訳ありませんが私はあなたが答えに向かっていたかを見ていない場合。 – Lynn

+0

これは何を意味するのですか? "WITH n(n)AS" – Lynn

関連する問題