-2

私はこのテーブルを持っています:

 CREATE TABLE [Alerts]
(
  [Timestamp] datetime,
  [Status] int
)

INSERT INTO [Alerts] ([Timestamp], [Status])
  VALUES
    ('2013-1-1 00:00:00', 1),
    ('2013-1-1 00:00:05', 1),
    ('2013-1-1 00:00:10', 2),
    ('2013-1-1 00:00:15', 2),
    ('2013-1-1 00:00:20', 0),
    ('2013-1-1 00:00:25', 1),
    ('2013-1-1 00:00:30', 1),
    ('2013-1-1 00:00:32', 2),
    ('2013-1-1 00:00:35', 2),
    ('2013-1-1 00:00:40', 0),
    ('2013-1-1 00:00:45', 0),
    ('2013-1-1 00:00:50', 0) 



以下のコードからトリガーを作成する方法:

SELECT
  MIN ([main].[Start]) AS [STOP_Begin],
  [main].[End] AS [STOP_End],
  DATEDIFF(s, MIN([main].[Start]), [main].[End]) AS [Interval_Second]
FROM
(
  SELECT
    [starts].[Start],
    MIN([ends].[Timestamp]) AS [End]
  FROM
  (
    SELECT
      [Timestamp] AS [Start]
    FROM [Alerts]
    WHERE [Status] = 0
  ) AS [starts] LEFT JOIN [Alerts] AS [ends]
  ON  [starts].[Start] < [ends].[Timestamp]
  AND [ends].[Status] <> 0
  GROUP BY
    [starts].[Start]
) AS [main]
GROUP BY
  [main].[End]
ORDER BY 1



したがって、テーブル [Alerts] に新しい入力を追加するたびに
、新しいテーブルが自動的に変更されます。
すでに新しいテーブルを作成する必要がありますか、またはどのようにしますか? 私のselectコードと同じことを行う
このLINK Triggerコードを見てください。新しいテーブル名 newtableと言うだけなので、新しい入力を追加するたびにselectコードを使用する必要はありません


4

1 に答える 1

0

このテーブルが用意されていると仮定して、実際に質問に答えるには:

CREATE TABLE NewTable 
(   Stop_Begin      DATETIME,
    Stop_End        DATETIME,
    Interval_Second INT
);

アラートにレコードが追加されるたびにこのテーブルを更新するトリガーを作成できます。

CREATE TRIGGER Alerts_Insert ON Alerts
FOR INSERT
AS
    TRUNCATE TABLE NewTable;

    INSERT NewTable
    SELECT  MIN ([main].[Start]) AS [STOP_Begin],
            [main].[End] AS [STOP_End],
            DATEDIFF(s, MIN([main].[Start]), [main].[End]) AS [Interval_Second]
    FROM    (   SELECT  [starts].[Start],
                        MIN([ends].[Timestamp]) AS [End]
                FROM    (   SELECT  [Timestamp] AS [Start]
                            FROM    [Alerts]
                            WHERE   [Status] = 0
                        ) AS [starts] 
                        LEFT JOIN [Alerts] AS [ends]
                            ON  [starts].[Start] < [ends].[Timestamp]
                            AND [ends].[Status] <> 0
                GROUP BY [starts].[Start]
            ) AS [main]
    GROUP BY [main].[End]
    ORDER BY 1; 

トリガーの SQL フィドル

ただし、これは、挿入するNewTable よりも頻繁にから選択していない限り、ほぼ確実に悪い設計でAlertsあり、選択クエリは瞬時ではありません。状況の 99% で、より実用的なアプローチは、単にNewTableビューとして持つことです。

CREATE VIEW dbo.NewTable 
AS
    SELECT  MIN ([main].[Start]) AS [STOP_Begin],
            [main].[End] AS [STOP_End],
            DATEDIFF(s, MIN([main].[Start]), [main].[End]) AS [Interval_Second]
    FROM    (   SELECT  [starts].[Start],
                        MIN([ends].[Timestamp]) AS [End]
                FROM    (   SELECT  [Timestamp] AS [Start]
                            FROM    [Alerts]
                            WHERE   [Status] = 0
                        ) AS [starts] 
                        LEFT JOIN [Alerts] AS [ends]
                            ON  [starts].[Start] < [ends].[Timestamp]
                            AND [ends].[Status] <> 0
                GROUP BY [starts].[Start]
            ) AS [main]
    GROUP BY [main].[End]
    ORDER BY 1; 

ビューの SQL フィドル

両方の SQL Fiddles を比較すると、右側の SQL は変更されておらず、結果も同じであることがわかります。ただし、ビューをNewTable使用すると、挿入のオーバーヘッドが少なくなり、問題が発生Alertsする場所が少なくなり、維持する必要がなくなります。

于 2013-01-31T08:50:31.000 に答える