-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] 中时,
它都会自动更改新表。
我应该已经制作新桌子还是如何制作?
请看这个LINK

触发器代码,它和我的选择代码一样,只是说新表名newtable
所以我每次添加新输入时都不需要使用我的选择代码

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 回答