SQL-从多个表中提取集合,分组,然后求和
我需要从表RawData和RawDataMeter中提取数据,并对过去10分钟内每个唯一MeterId的“Value”字段求和(相对于时间戳)。只有在BuildingMeter表中存在RawData.BuildingId和RawDataMeter.MeterId时,才会选择使用内部联接通过RawDataId字段联接的RawData和RawDataMeter表记录。也就是说,仅当BuildingMeter表中存在RawData和RawDataMeter表中的字段时,查询才需要从中选择字段,然后需要获取每个表的最新记录(基于时间戳),然后检索该表最近10分钟的值。一旦有了这些值,它需要将每米10分钟的值相加并输出结果 到目前为止,我的问题是:SQL-从多个表中提取集合,分组,然后求和,sql,sql-server,sql-server-2008,sql-server-2005,Sql,Sql Server,Sql Server 2008,Sql Server 2005,我需要从表RawData和RawDataMeter中提取数据,并对过去10分钟内每个唯一MeterId的“Value”字段求和(相对于时间戳)。只有在BuildingMeter表中存在RawData.BuildingId和RawDataMeter.MeterId时,才会选择使用内部联接通过RawDataId字段联接的RawData和RawDataMeter表记录。也就是说,仅当BuildingMeter表中存在RawData和RawDataMeter表中的字段时,查询才需要从中选择字段,然后需要
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米的建筑(这是可变的)):
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
这个怎么样:
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值。我希望这有帮助。这个怎么样:
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值。我希望这能有所帮助。我没有足够的时间编写查询 您需要执行以下操作:
在编写查询时,如果将别名放在所有字段名之前,则会有所帮助。普通读者无法分辨哪些字段来自哪些表。我没有足够的时间编写查询 您需要执行以下操作:
在编写查询时,如果将别名放在所有字段名之前,则会有所帮助。普通读者无法分辨哪些字段来自哪些表。当您说最后十分钟时,这是raewdata表中最近读取的最后十分钟?如果昨天一个计价器停止工作,那么今天的结果仍然是最后十分钟?嗨,托尼。10分钟是从仪表的最新读数算起的。因此,该表将包含一组读数,它们可能来自不同的日期。当你说最后十分钟时,这是raewdata表中最近一次读数的最后十分钟?如果昨天一个计价器停止工作,那么今天的结果仍然是最后十分钟?嗨,托尼。10分钟是从仪表的最新读数算起的。因此,该表将包含混合读数,它们可能来自不同的日期。10分钟,来自仪表的最新时间戳。理论上,每一米都可能有不同的时间戳。或者可能已经停止记录值了。@Aaron Bertrand抱歉,我通常使用postgreSQL。在SQL Server中,您必须使用“fn NOW()”或“CURRENT_TIMESTAMP”或“GETDATE()”。@Dan您能解释一下为什么要在RawDataId而不是MeterId上链接表吗。如果在RawData tabl和RawDataMeter表中有一个MeterId列,那么这会容易得多。对不起,我应该澄清一下。建筑物仪表的每组结果具有相同的时间戳,但不同建筑物仪表组的时间戳(最新读数)可能不同。10分钟,来自仪表的最新时间戳。理论上,每一米都可能有不同的时间戳。或者可能已经停止记录值了。@Aaron Bertrand抱歉,我通常使用postgreSQL。在SQL Server中,您必须使用“fn NOW()”或“CURRENT_TIMESTAMP”或“GETDATE()”。@Dan您能解释一下为什么要在RawDataId而不是MeterId上链接表吗。如果在RawData tabl和RawDataMeter表中有一个MeterId列,那么这会容易得多。对不起,我应该澄清一下。建筑物仪表的每一组结果都有相同的时间戳,但不同建筑物仪表组的时间戳(最新读数)可能不同。请尝试一下。字段名称上注明的点。谢谢。我会试试这个。字段名称上注明的点。非常感谢。