0

StartTime と StopTime を持つテーブルのすべての行を日に分割したいと考えています。

例:

User    Site    Title    TimeStampStart(01-11-2013)    TimeStampStop(05-11-2013)

タイムスタンプとして間隔に日を含む5つの行を取得したいと思います:

User    Site    Title    TimeStampStart(01-11-2013)
User    Site    Title    TimeStampStart(02-11-2013)
User    Site    Title    TimeStampStart(03-11-2013)
User    Site    Title    TimeStampStart(04-11-2013)
User    Site    Title    TimeStampStart(05-11-2013)

2 つのタイムスタンプから日数を分割できる ListDates 関数を作成しましたが、テーブルを引数として使用する必要があるため使用できません。

4

2 に答える 2

3

数字の表がある場合、これはかなり簡単です。

CREATE TABLE dbo.Numbers(n INT PRIMARY KEY);

INSERT dbo.Numbers(n) SELECT TOP (1000) rn = ROW_NUMBER() OVER 
  (ORDER BY [object_id]) FROM sys.all_objects;

-- if you may have dates that may be more than 1000 days apart (~3 years), 
-- increase TOP and use a cross join against one of the other system views

それで:

SELECT s.Site, DATEADD(DAY, n.n, TimeStampStart)
FROM dbo.YourTable AS s
INNER JOIN dbo.Numbers AS n
ON n.n <= DATEDIFF(DAY, s.TimeStampStart, s.TimeStampStop);

SQLFiddle デモ

セットを生成する多くの例 (および数値テーブルが一般的に最適に機能する理由):

http://sqlperformance.com/generate-a-set-1

http://sqlperformance.com/generate-a-set-2

http://sqlperformance.com/generate-a-set-3

于 2013-11-05T16:20:20.657 に答える
0

システム テーブル Master..spt_values を使用して整数の連続したリストを取得し、これをソースに結合して、毎回開始日に整数を追加します (そして終了日に停止します)。例えば

DECLARE @T TABLE (TimestampStart DATETIME2, TimestampStop DATETIME2);
INSERT @T VALUES ('20131101', '20131105');

SELECT  Date = DATEADD(DAY, spt.Number, t.TimeStampStart)
FROM    @t t
        INNER JOIN master..spt_values spt
            ON spt.Number <= DATEDIFF(DAY, t.TimestampStart, t.TimestampStop)
            AND spt.Type = 'P';

Microsoft が「文書化されていない」テーブルを削除するMaster..spt_valuesか、日付が 2047 日以上離れていることを懸念している場合は、別の方法で番号のリストを生成できます。

DECLARE @T TABLE (TimestampStart DATETIME2, TimestampStop DATETIME2);
INSERT @T VALUES ('20131101', '20131105');

WITH Numbers AS 
(   SELECT  TOP 100000 Number = ROW_NUMBER() OVER(ORDER BY a.Object_ID) - 1
    FROM    sys.all_objects a
            CROSS JOIN sys.all_objects b
)
SELECT  Date = DATEADD(DAY, n.Number, t.TimestampStart)
FROM    @T t
        INNER JOIN Numbers n
            ON n.Number <= DATEDIFF(DAY, t.TimestampStart, t.TimestampStop);

または、必要なたびにその場で生成する必要なく、何度でも使用できる独自の数値表を作成します。

于 2013-11-05T16:13:13.110 に答える