0

id_measure_typeそれらを識別するためにを使用して、さまざまなタイプのメジャーを含むテーブルがあります。その期間と各単位 ( ) の合計をすべて取得する SELECT を実行する必要がありますが、id_unit一部のメジャーが空の場合は、別のメジャーを取得するなどです。

測定値は、日付、単位、および時間ごとです。これは私のテーブルの要約です:

id_unit date入札時間 id_measure_type メジャー
252 2013/05/22 11 6 500
252 2013/05/22 11 4 250
252 2013/05/22 11 1 300
107 2013 年 5 月 22 日 11 4 773
107 2013/05/22 11 1 500
24 2013/05/22 11 6 0
24 2013/05/22 11 4 549
24 2013/05/22 11 1 150

すべての入力データ範囲に対して を作成し、SUM次の順序で「最適な」メジャー タイプを取得する選択が必要です。0.id_measure_type = 6id_measure_type = 4id_measure_type = 1

タイプ 6 のすべてのメジャーがある限り、この選択は正しいです。

SELECT id_unit, SUM(measure) AS measure
FROM UNIT_MEASURES
WHERE dateBid BETWEEN '03/23/2013' AND '03/24/2013' AND id_unit IN (325, 326) 
AND id_measure_type = 6 GROUP BY id_unit

入力は、日付の範囲と単位です。1回の選択でそれを行う方法はありますか?

編集:
必要に応じて、すべての日付と時間を含むテーブル もあるcalendarので、(1 時間ごとに取得するために) 結合するために使用できます。

編集:
値が になることはありませんNULL。「空または 0」の場合、値が 0 または 1 時間欠落していることを意味します。「最良の」可能なタイプのメジャーから、可能なすべての時間がSUMに含まれている必要があります。

4

3 に答える 3

1

私はあなたを正しく理解しているかどうかはわかりませんが、これでうまくいくと思います (あなたのテーブルに変更してください)

テストのセットアップ:

DECLARE @Table TABLE ([id_unit] INT, [dateBid] DATE, [hour] INT, [id_measure_type] INT, [measure] INT);

INSERT INTO @Table
    SELECT *
      FROM (
        VALUES (252, GETDATE(), 11, 6, 500)
             , (252, GETDATE(), 11, 4, 250)
             , (252, GETDATE(), 11, 1, 300)
             , (107, GETDATE(), 11, 4, 773)
             , (107, GETDATE(), 11, 1, 500)
         ) [Values]([id_unit], [dateBid], [hour], [id_measure_type], [measure]);

実際のクエリ:

WITH [Filter] AS (
    SELECT *
         , DENSE_RANK() OVER(PARTITION BY [id_unit] ORDER BY [id_measure_type] DESC) [Rank]
      FROM @Table
     WHERE [measure] > 0
)
SELECT [id_unit], SUM([measure])
  FROM [Filter]
 WHERE [Rank] = 1
   AND [id_unit] IN (252, 107)
   AND [dateBid] BETWEEN CAST(GETDATE()-1 AS DATE) AND CAST(GETDATE() AS DATE)
 GROUP BY [id_unit];

SUM() の前の出力のビュー:

WITH [Filter] AS (
    SELECT *
         , DENSE_RANK() OVER(PARTITION BY [id_unit] ORDER BY [id_measure_type] DESC) [Rank]
      FROM @Table
     WHERE [measure] > 0
)
SELECT *
  FROM [Filter]
 WHERE [Rank] = 1
   AND [id_unit] IN (252, 107)
   AND [dateBid] BETWEEN CAST(GETDATE()-1 AS DATE) AND CAST(GETDATE() AS DATE);

編集(毎時): テーブルにさらにデータがあるかどうかはわかりません。上記のサンプルでは、​​合計は(私が知る限り)とにかく1行のみSUM()になりますが、それでも機能するので私は'入れておきます。

WITH [Filter] AS (
    SELECT *
         , DENSE_RANK() OVER(PARTITION BY [id_unit], [Hour] ORDER BY [id_measure_type] DESC) [Rank]
      FROM @Table
     WHERE [measure] > 0
)
SELECT [id_unit], [Hour], SUM([measure])
  FROM [Filter]
 WHERE [Rank] = 1
   AND [id_unit] IN (252, 107)
   AND [dateBid] BETWEEN CAST(GETDATE()-1 AS DATE) AND CAST(GETDATE() AS DATE)
 GROUP BY [id_unit], [Hour];
于 2013-05-22T09:54:45.840 に答える
0

Don answerは完全に機能しますが、テーブルには大量のデータがあるため、選択を行うのに 3 分以上かかります。

私は独自のソリューションを作成しました。これは大きくて醜いですが、見た目は高速です(約1秒続きます):

SELECT tUND.id_unit, ROUND(SUM(
    CASE WHEN ISNULL(t1.measure, 0) > 0 THEN t1.measure ELSE 
    CASE WHEN ISNULL(t2.measure, 0) > 0 THEN t2.measure ELSE
    CASE WHEN ISNULL(t3.measure, 0) > 0 THEN t3.measure ELSE 0 
    END END END END
/1000),3) AS myMeasure
FROM calendar
LEFT OUTER JOIN UNITS_TABLE tUND ON tUND.id_unit IN (252, 107)
LEFT OUTER JOIN MEASURES_TABLE t1 ON t1.id_measure_type = 6 
    AND t1.dateBid = dt AND t1.hour = h AND t1.id_uf = tUND.id_uf
LEFT OUTER JOIN MEASURES_TABLE t2 ON t2.id_unit = t1.id_unit 
    AND t2.dateBid = t1.dateBid AND t2.id_measure_type = 1 
    AND t2.id_unit = tUND.id_unit 
LEFT OUTER JOIN MEASURES_TABLE t3 ON tCNT.id_unit = tUFI.id_unit
    AND t3.dateBid = t1.dateBid AND t3.id_measure_type = 4 
    AND t3.id_unit = tUND.id_unit 
WHERE dt BETWEEN '03/23/2013' AND '03/24/2013' 
GROUP BY tUND.id_unit
于 2013-05-23T10:26:51.357 に答える
0

あなたが提供したすべてのサンプル行が同じ値を持ち、nomeasureが 0 であることを考えると、いくつかの列がどのように関連しているかはわかりませんが、あなたが望むのはこれらの行に沿っていると思います:

;With Priorities as (
    select *,ROW_NUMBER() OVER (
         PARTITION BY id_unit,dateBid,hour
         ORDER BY CASE
             WHEN COALESCE(measure,0) > 0 THEN id_measure_type
             else -1 END desc) as priority
    from @t
)
select id_unit,SUM(measure)
from Priorities
where priority = 1
group by id_unit

id_measure_typenoが 0 未満であり、no が 0 未満であると仮定すると、measureこれらが要件である場合、これらを適応させることができます。

COALESCE( 「空または0」の要件が実際にNULLsと0について話しているという前提で、を追加しました)

于 2013-05-22T09:40:30.343 に答える