2

我需要从表 RawData 和 RawDataMeter 中提取数据,并对过去 10 分钟内每个唯一 MeterId 的“值”字段求和(相对于时间戳)。RawData 和 RawDataMeter 表通过 RawDataId 字段使用 INNER JOIN 连接,只有在 BuildingMeter 表中存在 RawData.BuildingId 和 RawDataMeter.MeterId 时才会选择记录。即查询需要从 RawData 和 RawDataMeter 表中选择字段,前提是它们存在于 BuildingMeter 表中,然后需要获取每个仪表的最新记录(基于时间戳),然后检索最后 10 分钟的值。仪表。一旦有了这些值,它需要对每米 10 分钟的值求和并输出结果。

到目前为止我的查询是:

SELECT TOP (SELECT COUNT(DISTINCT BuildingMeterId) FROM BuildingMeter)
    MeterId, BuildingId, TimeStamp, Value
FROM
    RawData
    INNER JOIN 
        RawDataMeter 
    ON RawData.RawDataId = RawDataMeter.RawDataId
WHERE
    EXISTS
        (SELECT 
            BuildingId,
            BuildingMeterId
        FROM
            BuildingMeter)
ORDER BY
    TimeStamp DESC

这会产生以下结果:

1   1   2012-05-16 12:51:00.000 216
2   1   2012-05-16 12:51:00.000 876989
3   1   2012-05-16 12:51:00.000 389164
4   1   2012-05-16 12:51:00.000 1.298896E+07
5   1   2012-05-16 12:51:00.000 283378
6   1   2012-05-16 12:51:00.000 1541438
7   1   2012-05-16 12:51:00.000 4241823
8   1   2012-05-16 12:51:00.000 5761659
9   1   2012-05-16 12:51:00.000 3
10  1   2012-05-16 12:51:00.000 0
11  1   2012-05-16 12:51:00.000 23
12  1   2012-05-16 12:51:00.000 3822836
13  1   2012-05-16 12:51:00.000 4983960
14  1   2012-05-16 12:51:00.000 909497
15  1   2012-05-16 12:51:00.000 7724438

BuildingMeter 表示例(我只包括 1 座 15 米的建筑物(这是可变的)):

BuildingId  BuildingMeterId
1   1
1   2
1   3
1   4
1   5
1   6
1   7
1   8
1   9
1   10
1   11
1   12
1   13
1   14
1   15

RawData 中最后 30 条记录的样本数据:

RawDataId, TimeStamp, BuildingId
21677   2012-05-16 00:03:00.000 1
21678   2012-05-16 00:03:00.000 1
21679   2012-05-16 00:03:00.000 1
21680   2012-05-16 00:03:00.000 1
21681   2012-05-16 00:03:00.000 1
21682   2012-05-16 00:03:00.000 1
21683   2012-05-16 00:03:00.000 1
21684   2012-05-16 00:03:00.000 1
21685   2012-05-16 00:03:00.000 1
21686   2012-05-16 00:03:00.000 1
21687   2012-05-16 00:03:00.000 1
21688   2012-05-16 00:03:00.000 1
21689   2012-05-16 00:03:00.000 1
21690   2012-05-16 00:03:00.000 1
21691   2012-05-16 00:03:00.000 1
21662   2012-05-16 00:02:00.000 1
21663   2012-05-16 00:02:00.000 1
21664   2012-05-16 00:02:00.000 1
21665   2012-05-16 00:02:00.000 1
21666   2012-05-16 00:02:00.000 1
21667   2012-05-16 00:02:00.000 1
21668   2012-05-16 00:02:00.000 1
21669   2012-05-16 00:02:00.000 1
21670   2012-05-16 00:02:00.000 1
21671   2012-05-16 00:02:00.000 1
21672   2012-05-16 00:02:00.000 1
21673   2012-05-16 00:02:00.000 1
21674   2012-05-16 00:02:00.000 1
21675   2012-05-16 00:02:00.000 1
21676   2012-05-16 00:02:00.000 1

RawDataMeter 示例:

MeterId, RawDataId, Value
15  21691   7722613
14  21690   908944
13  21689   4982947
12  21688   3821899
11  21687   6
10  21686   0
9   21685   0
8   21684   5761656
7   21683   4240048
6   21682   1541372
5   21681   283223
4   21680   1.298603E+07
3   21679   388137
2   21678   876121
1   21677   0
15  21676   7722615
14  21675   908944
13  21674   4982947
12  21673   3821899
11  21672   5
10  21671   0
9   21670   0
8   21669   5761656
7   21668   4240052
6   21667   1541372
5   21666   283223
4   21665   1.298604E+07
3   21664   388137
2   21663   876122
1   21662   0

编辑:

按照 Gordon 概述的步骤,我设法获得了以下 SQL 查询,它似乎工作正常:

WITH 
    RawMeterData (MeterId, BuildingId, TimeStamp, LatestTimeStamp, Value) AS
(SELECT
    RawDataMeter.MeterId, 
    RawData.BuildingId, 
    RawData.TimeStamp, 
    MAX(RawData.TimeStamp) OVER (PARTITION BY BuildingMeter.BuildingMeterId) AS LatestTimeStamp, 
    RawDataMeter.Value
FROM
    BMS_RawData AS RawData
    INNER JOIN 
        BMS_RawDataMeter AS RawDataMeter 
    ON RawData.RawDataId = RawDataMeter.RawDataId
    INNER JOIN
        (SELECT 
            DISTINCT BuildingId,
            BuildingMeterId
        FROM
            AST_BuildingMeter) as BuildingMeter 
        ON RawData.BuildingId = BuildingMeter.BuildingId AND 
        RawDataMeter.MeterId = BuildingMeter.BuildingMeterId)
SELECT MeterId, BuildingId, SUM(Value) AS Value FROM RawMeterData WHERE RawMeterData.TimeStamp 
BETWEEN DATEADD(mi, -9, LatestTimeStamp) AND LatestTimeStamp
GROUP BY MeterId, BuildingId
4

2 回答 2

0

这个怎么样:

select
  RawDataMeter.MeterId,
  RawDataMeter.BuildingId,
  sum(Value) as sumvalue
from
  RawData,
  RawDataMeter
where
  RawData.RawDataId=RawDataMeter.RawDataId
  RawData.TimeStamp > now() - 10*'1 minute'::interval
group by
  RawDataMeter.MeterId,
  RawDataMeter.BuildingId
order by
  RawDataMeter.MeterId,
  RawDataMeter.BuildingId

如果您的索引制作正确,那么这应该会运行得相当快。此外,您在 RawDataId 上的表之间进行链接似乎很奇怪。我原以为您会链接 MeterId 值。我希望这有帮助。

于 2012-05-19T13:10:10.803 回答
0

我没有足够的时间来编写查询。

您需要执行以下操作:

  1. 将两个字段上的存在子句更改为连接。您应该在内部选择中添加“不同”以防止重复影响您。
  2. 使用 windows 函数“max(timestamp) over (partition by buildingmeterid)”获取最新的时间戳。
  3. 将其设为子查询(或使用“with”子句)。
  4. 根据最大时间戳和时间戳之间的差异选择记录
  5. 汇总结果以获得总和。

为了编写查询,如果您在所有字段名称前放置别名,将会有所帮助。不经意的读者无法分辨哪些字段来自哪些表。

于 2012-05-19T13:21:32.843 回答