SQL Group By Query中的添加列

时间:2015-01-12 22:04:37

标签: sql sql-server group-by aggregate-functions

我正在尝试聚合通过4个表链接的数据,并根据最后一个表中包含的每个房间的第一个表中的时间戳条目返回最后一个链接的行。

当我使用以下查询时,我会根据需要对条目进行优先级排序和分组:

SELECT 
    RoomName,
    CRV_SignalLog.SignalID,
    Max(LogTimeStamp) As LogTime
FROM 
    [CRV_SignalLog]
    inner Join [CRV_SymbolSignals]
        on CRV_SignalLog.SignalID = CRV_SymbolSignals.SignalID
    inner Join [CRV_Symbols]
        on CRV_SymbolSignals.SymbolID = CRV_Symbols.SymbolID
    inner Join [CRV_Rooms]
        on CRV_Symbols.RoomID = CRV_Rooms.RoomID
Where 
    AttributeID = 'Display_Power'
Group By 
    RoomName, 
    CRV_SignalLog.SignalID
Order By 
    LogTime Desc 

我得到了每个房间的最后一个LogTime条目的所有房间的列表。但是我需要从CRV_SignalLog表中添加另一个字段来了解该信号的当前状态。

我一直在研究并基于其他答案,我认为我可以将这些结果与CRV_SignalLog表连接,以便像这样添加该表中的其他列:

SELECT
    RoomName,
    DigitalValue,
    LastEntry.LogTime
From
    (SELECT 
        RoomName,
        CRV_SignalLog.SignalID,
        Max(LogTimeStamp) as LogTime
    FROM 
        [CRV_SignalLog]
        inner Join [CRV_SymbolSignals]
            on CRV_SignalLog.SignalID = CRV_SymbolSignals.SignalID
        inner Join [CRV_Symbols]
            on CRV_SymbolSignals.SymbolID = CRV_Symbols.SymbolID
        inner Join [CRV_Rooms]
            on CRV_Symbols.RoomID = CRV_Rooms.RoomID
    where 
        AttributeID = 'Display_Power'
    Group By 
        RoomName, 
        CRV_SignalLog.SignalID
    ) LastEntry
    Inner Join CRV_SignalLog 
        on CRV_SignalLog.SignalID = LastEntry.SignalID 
Order By 
    RoomName

但是,不幸的是,这会导致结果爆炸 - 我想为每个匹配的' AttributeID =' Display_Power'返回一行。但是每个房间显示最后一个条目的时间戳。

我错过了什么?

1 个答案:

答案 0 :(得分:0)

正在发生的是,您正在获取CRV_SignalLog中与SignalID字段的子查询结果匹配的每一行的结果。换句话说,在子查询中应用分组依据后,它正在LastEntry和CRV_SignalLog之间进行连接。

我会尝试在CRV_SignalLog.LogTimeStamp和LastEntry.LogTime字段之间添加另一个连接条件,如下所示:

SELECT
    RoomName,
    DigitalValue,
    LastEntry.LogTime
From
    (SELECT 
        RoomName,
        CRV_SignalLog.SignalID,
        Max(LogTimeStamp) as LogTime
    FROM 
        [CRV_SignalLog]
        inner Join [CRV_SymbolSignals]
            on CRV_SignalLog.SignalID = CRV_SymbolSignals.SignalID
        inner Join [CRV_Symbols]
            on CRV_SymbolSignals.SymbolID = CRV_Symbols.SymbolID
        inner Join [CRV_Rooms]
            on CRV_Symbols.RoomID = CRV_Rooms.RoomID
    where 
        AttributeID = 'Display_Power'
    Group By 
        RoomName, 
        CRV_SignalLog.SignalID
    ) LastEntry
    Inner Join CRV_SignalLog 
        on CRV_SignalLog.SignalID = LastEntry.SignalID 
        AND CRV_SignalLog.LogTimeStamp = LastEntry.LogTime
Order By 
    RoomName

我假设LogTimeStamp在CRV_SignalLog表上。

由于您担心LogTimeStamp是否足够独特,下面是另一个使用子查询获取DigitalValue的示例,并确保您只获得一个:

SELECT
    RoomName,
    (SELECT TOP 1 
        DigitalValue
     FROM
        CRV_SignalLog dvLog
     WHERE
        dvLog.SignalID = LastEntry.SignalID
        AND dvLog.LogTimeStamp = LastEntry.LogTime
    ) DigitalValue,
    LastEntry.LogTime
From
    (SELECT 
        RoomName,
        CRV_SignalLog.SignalID,
        Max(LogTimeStamp) as LogTime
    FROM 
        [CRV_SignalLog]
        inner Join [CRV_SymbolSignals]
            on CRV_SignalLog.SignalID = CRV_SymbolSignals.SignalID
        inner Join [CRV_Symbols]
            on CRV_SymbolSignals.SymbolID = CRV_Symbols.SymbolID
        inner Join [CRV_Rooms]
            on CRV_Symbols.RoomID = CRV_Rooms.RoomID
    where 
        AttributeID = 'Display_Power'
    Group By 
        RoomName, 
        CRV_SignalLog.SignalID
    ) LastEntry
Order By 
    RoomName