簡體   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