计算超过24小时的时间时,无法更新视图/函数'cte',因为其中包含汇总

时间:2019-01-30 11:02:04

标签: sql-server sql-update aggregate-functions

我有一个带有列的数据表alarms,其中两个是:tmStartTimetmEndtime。我想以小时为单位计算总的活动时间tmTotals,这可能超过24小时。例如24:00:04

我的数据表Alarms(我在这里使用数据类型TIME,在少于24小时的时间内工作正常):

tmStarttime               tmEndTime                 tmTotals
--------------------------------------------------------------
2018-12-03 00:00:19.257   2018-12-04 00:00:23.288   00:00:04  (is actually 24:00:04)
2018-12-03 23:59:16.817   2018-12-04 00:01:42.942   00:02:26
2018-12-03 23:59:45.005   2018-12-04 00:07:03.650   00:07:18
2018-12-03 23:11:57.645   2018-12-04 00:07:16.785   00:55:19
2018-12-04 00:03:52.086   2018-12-04 00:07:37.991   00:03:45
2018-12-04 00:07:16.787   2018-12-04 00:08:14.302   00:00:57
2018-12-04 00:08:30.430   2018-12-04 00:08:34.480   00:00:04

经过24小时,我发现我应该这样做:

UPDATE Messages_History
SET tmTotals
= right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) / 3600 )),2) + ':'
+ right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) / 60 ) % 60 ),2) + ':'
+ right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) %60 )),2)

在这里我得到了错误:

An aggregate may not appear in the set list of an UPDATE statement.

然后我发现我应该这样做:

    WITH cte

    AS (SELECT new_tmTotals 
    = right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) / 3600 )),2) + ':'
    + right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) / 60 ) % 60 ),2) + ':'
    + right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) %60 )),2), tmTotals
    FROM Messages_History
    GROUP BY tmTotals)

    UPDATE cte
    SET tmTotals = new_tmTotals

执行存储过程时出现错误:

Cannot update the view or function 'cte' because it contains aggregates, or a DISTINCT or GROUP BY clause, or PIVOT or UNPIVOT operator.

我有点不知道现在要做什么,我发现了一些有关删除重复行的内容,但是我需要保留重复项。

2 个答案:

答案 0 :(得分:1)

或者,您可以尝试使用联接进行更新:

UPDATE mh1
SET tmTotals = mh2.new_tmTotals
FROM Messages_History mh1
INNER JOIN
(
    SELECT
        tmTotals,
           RIGHT('0' + convert(varchar(9),
           (sum(datediff(second,tmStartTime,tmEndTime)) / 3600 )),2) + ':' +
           RIGHT('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) / 60 ) % 60 ),2) + ':' +
           RIGHT('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) %60 )),2) AS new_tmTotals
    FROM Messages_History
    GROUP BY tmTotals
) mh2
    ON mh1.tmTotals = mh2.tmTotals;

该错误的基本问题是您正在尝试更新派生(汇总)表,而SQL Server拒绝决定应如何更新原始基础表。

答案 1 :(得分:0)

PrimaryUnique键添加到表中以解决此问题。然后使用下面的一个...

WITH cte

AS (SELECT UniqueID 'Uniq_ID',new_tmTotals = right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) / 3600 )),2) + ':'
+ right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) / 60 ) % 60 ),2) + ':'
+ right ('0' + convert(varchar(9),(sum(datediff(second,tmStartTime,tmEndTime)) %60 )),2), tmTotals
FROM Messages_History
GROUP BY tmTotals)

UPDATE cte
SET tmTotals = new_tmTotals
WHERE UniqueID = Uniq_ID