2

RawDataテーブルとRawDataMeterテーブルからデータを抽出し、過去10分間の一意のMeterIdごとに「Value」フィールドを合計する必要があります(TimeStampと比較して)。内部結合を使用してRawDataIdフィールドを介して結合されたRawDataテーブルとRawDataMeterテーブルでは、RawData.BuildingIdとRawDataMeter.MeterIdがBuildingMeterテーブル内に存在する場合にのみレコードが選択されます。つまり、クエリは、BuildingMeterテーブルに存在する場合にのみRawDataテーブルとRawDataMeterテーブルからフィールドを選択する必要があります。次に、各メーターの最新のレコード(TimeStampに基づく)を取得し、その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テーブルのサンプル(15メートルの建物を1つだけ含めました(これは可変です)):

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つのフィールドで、exists句を結合に変更します。重複があなたに影響を与えるのを防ぐために、内側の選択に「個別」を追加する必要があります。
  2. 最新のタイムスタンプを取得するには、ウィンドウ関数 "max(timestamp)over(partition by buildingmeterid)"を使用します。
  3. これをサブクエリにします(または「with」句を使用します)。
  4. 最大タイムスタンプとタイムスタンプの差に基づいてレコードを選択します
  5. 結果を集計して合計を取得します。

クエリを作成するには、すべてのフィールド名の前にエイリアスを配置すると便利です。カジュアルな読者は、どのフィールドがどのテーブルからのものかわかりません。

于 2012-05-19T13:21:32.843 に答える