繁体   English   中英

Sum 然后在一个 VIEW 中按子句划分为一个组

[英]Sum then Divide in a Group by Clause in a VIEW

所以基本上在创建一个带有case语句的视图之后。 我想在下面的当前视图中添加一个 group by 子句。 我该怎么做? group by 语句示例和 case 语句示例如下

查看有效的案例声明:

Create View v_ClassroomOccupancyJulytest
AS
Select 
ro.[RoomCode],
ro.[RoomName],
ro.[DeviceID],
ro.[Temperature],
ro.[LocalTime],
ctt.[DAY],
ctt.[DATETIME],
ctt.[DURATION],

CASE

WHEN (ro.LocalTime BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE)  
    AND ro.Occupancy = 1 THEN 'Booked And Occupied'

WHEN (ro.LocalTime NOT BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE ) or ctt.CLASSSTARTDATE IS NULL and ctt.CLASSENDDATE IS NULL
    AND ro.Occupancy = 1 THEN 'Not Booked but Occupied'

WHEN (ro.LocalTime BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE)
    AND ro.Occupancy = 0 THEN 'Booked but Not Occupied'

ELSE 'Not booked and Not Occupied' 

END AS ClassroomStatus


FROM V_RoomOccupancyJuly ro
left outer JOIN ClassTimeTable ctt
ON ro.RoomCode = ctt.ROOMID and (ro.LocalTime BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE)

我想使用 group by 根据[roomcode][datetime] 30 分钟间隔和sum([occupancy])/3对行进行分组。

我使用下面的group by子句代码运行我的创建视图,它返回一个错误:

不能在用于 GROUP BY 子句的 group by 列表的表达式中使用聚合或子查询

组的一个例子

更新

这是现在的视图:

CREATE VIEW [iot].[v_test]
AS
SELECT
    ro.[RoomCode],
    ro.[RoomName],
    ro.[DeviceID],
    ro.[TpID],
    CAST(avg(ro.[Temperature]) AS decimal(10, 1)) AS [Temperature],
    CASE
        WHEN avg(cast(occupancy as decimal)) between 0.01 and 1.0 
            THEN '1'
        ELSE
            '0'
    END AS Occupancy,
    (DATEADD(HOUR, DATEPART(HOUR, ro.[LocalTime]), DATEADD( MINUTE, 30 * CAST((DATEDIFF(MINUTE, '19000101', ro.[LocalTime]) / 30) % 2 AS INT),
    CAST(CAST(ro.[LocalTime] AS DATE) AS DATETIME)))) AS [Time],
    ctt.[DAY],
    ctt.[CLASSSTARTDATE],
    ctt.[CLASSENDDATE],
    ctt.[SUBJECTCODE],
    ctt.[SEMESTERID],
    ctt.[DURATION],
    cs.ClassroomStatus
FROM
    [iot].[v_RoomOccupancy] ro
    LEFT OUTER JOIN
        [iot].[ClassTimeTable]  ctt
            ON ro.RoomCode = ctt.ROOMID
                AND (ro.LocalTime
                BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE
                    )
    CROSS APPLY
    (
        SELECT
            CASE
                WHEN (ro.LocalTime BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE)
                        AND (cast(occupancy as decimal) between 0.1 and 1.0 )
                    THEN 'Booked And Occupied'
                WHEN ((ro.LocalTime NOT BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE) OR ( ctt.CLASSSTARTDATE IS NULL AND ctt.CLASSENDDATE IS NULL))
                        AND (cast(occupancy as decimal) between 0.1 and 1.0 )
                    THEN 'Not Booked but Occupied'
                WHEN (ro.LocalTime BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE)
                        AND cast(occupancy as decimal) <= 0.0
                    THEN 'Booked but Not Occupied'
                WHEN ((ro.LocalTime NOT BETWEEN ctt.CLASSSTARTDATE AND ctt.CLASSENDDATE) OR (ctt.CLASSSTARTDATE IS NULL AND ctt.CLASSENDDATE IS NULL))
                        AND cast(occupancy as decimal) <= 0.0 
                    THEN 'Not Booked and Not Occupied'
                ELSE
                    'Null'
            END AS ClassroomStatus
    )AS cs
GROUP BY
    ro.[RoomCode],
    ro.[RoomName],
    ro.[DeviceID],
    ro.[TpID],

    (DATEADD(HOUR, DATEPART(HOUR, ro.[LocalTime]), DATEADD( MINUTE, 30 * CAST((DATEDIFF(MINUTE, '19000101', ro.[LocalTime]) / 30) % 2 AS INT),
    CAST(CAST(ro.[LocalTime] AS DATE) AS DATETIME)))),
    ctt.[DAY],
    ctt.[CLASSSTARTDATE],
    ctt.[CLASSENDDATE],
    ctt.[SUBJECTCODE],
    ctt.[SEMESTERID],
    ctt.[DURATION],
    cs.ClassroomStatus;

现在的问题是,因为行是根据列分组的,那些最初有 2 行,占用值为 '1' 和 '0' 并且当组合时的平均值为 0.5,sql 服务器将其视为 0。

这是一个例子:

原始数据

原始数据

运行VIEW后的数据:

在此处输入图像描述

它应该是什么:

在此处输入图像描述

根据评论,您可以尝试:

CREATE VIEW v_ClassroomOccupancyJulytest
AS
    SELECT  ro.[RoomCode] ,
            ro.[RoomName] ,
            ro.[DeviceID] ,
            AVG(ro.[Temperature]) AS [Temperature] ,
            CASE WHEN ( SUM(Occupancy) / 3 ) > 0 THEN '1'
                 ELSE '0'
            END AS [1/2HrOccupancy] ,
            ctt.[DAY] ,
            ctt.[DATETIME] ,
            ctt.[DURATION] ,
            cs.ClassroomStatus
    FROM    V_RoomOccupancyJuly ro
            LEFT OUTER JOIN ClassTimeTable ctt ON ro.RoomCode = ctt.ROOMID
                                                  AND ( ro.LocalTime BETWEEN ctt.CLASSSTARTDATE
                                                              AND
                                                              ctt.CLASSENDDATE )
            CROSS APPLY ( SELECT    CASE WHEN ( ro.LocalTime BETWEEN ctt.CLASSSTARTDATE
                                                             AND
                                                              ctt.CLASSENDDATE )
                                              AND ro.Occupancy = 1
                                         THEN 'Booked And Occupied'
                                         WHEN ( ro.LocalTime NOT BETWEEN ctt.CLASSSTARTDATE
                                                             AND
                                                              ctt.CLASSENDDATE )
                                              OR ctt.CLASSSTARTDATE IS NULL
                                              AND ctt.CLASSENDDATE IS NULL
                                              AND ro.Occupancy = 1
                                         THEN 'Not Booked but Occupied'
                                         WHEN ( ro.LocalTime BETWEEN ctt.CLASSSTARTDATE
                                                             AND
                                                              ctt.CLASSENDDATE )
                                              AND ro.Occupancy = 0
                                         THEN 'Booked but Not Occupied'
                                         ELSE 'Not booked and Not Occupied'
                                    END AS ClassroomStatus
                        ) AS cs
    GROUP BY ro.[RoomCode] ,
            ro.[RoomName] ,
            ro.[DeviceID] ,
            ctt.[DAY] ,
            ctt.[DATETIME] ,
            ctt.[DURATION] ,
            cs.ClassroomStatus;

以下查询应该是有效的:

SELECT
    RoomCode,
    CONVERT(varchar(13), DATETIME, 120),  -- date and hour
    DATEPART(MINUTE, [DATETIME]) / 30,      -- 30 minute interval
    CASE WHEN SUM([OCCUPANCY]) / 3 > 0 THEN '1' ELSE '0' END AS [1/2HrOccupancy]
FROM yourTable
GROUP BY
    RoomCode,
    CONVERT(varchar(13), DATETIME, 120),  -- date and hour
    DATEPART(MINUTE, [DATETIME]) / 30;      -- 30 minute interval

在这里,我们按房间代码和 30 分钟间隔进行汇总。 然后,我们使用包含占用总和的CASE表达式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM