1

次のような構造のテーブルがあるとします。

id     dt        val
a     1/1/2012   23
a     2/1/2012   24
a     6/1/2013   12
a     7/1/2013   56
b     1/1/2009   34
b     3/1/2009   78

Everyidにはdt、月の形の と値があります。欠けている月があるかもしれませんが、月が重複することはありません。

各データ ポイントの 12 か月のローリング平均を計算する必要があります。たとえば、4 行目は (56+12)/12 になります。3 行目は (12)/12 になります。2 行目は (24+23)/12 などになります。特定の ID の最大移動平均の月 (および値) を特定する必要があります。

これは SQL 自体でもできることですか、それともデータセットをエクスポートして他の方法を使用する必要がありますか? 何百万行もあるから、できればSQLでやりたい。いくつかの MA メソッドを見てきましたが、私がやろうとしていることがうまくいくかどうかはわかりません。

私が使用している SQL は、Teradata で使用される派生物です。私が使用する必要があったほとんどの標準機能をサポートしています。

4

3 に答える 3

4

サブクエリを式として使用するだけです。

SELECT id, 
       dt, 
       val, 
       (
        SELECT SUM(val)/12 
        FROM mytable t2 
        WHERE t2.id = t.id
          AND t2.dt > DATEADD(mm, -12, t.dt) 
          AND t2.dt < t.dt
       ) val12MonthAvg 
FROM mytable t

ただし、数百万または行の場合、非常に遅くなる可能性があります。

于 2013-08-01T20:18:56.440 に答える
1

仮定:

  • あなたの日付形式はm/d/yyyyです(私はmm/dd/yyyy形式を使用しました)
  • このテーブルの id は、id が PK である他のエンティティへの FK です。
  • 選択した行の日付を取得し、その行とその ID の 12 か月未満のすべての行を探し、それらの行の値を合計することを意図しています。

これは私が使用しているものであり、あなたが指定しなかったため、Oracle SQLで記述します;)

クエリの概要:

  • 「Chosen」は、入力行として機能するテーブルのインスタンスです
  • 「ルックバック」は、選択した行を含むすべての行と、最大 12 か月前から 1 日を引いた期間を収集します
  • あなたの答えのためにlookback.valを合計してください
WITH DateTable
      AS (SELECT 'a' id, TO_DATE ('01/01/2012', 'mm/dd/yyyy') dt, 23 val FROM DUAL
            UNION
            SELECT 'a', TO_DATE ('1/1/2012', 'mm/dd/yyyy'), 23 FROM DUAL
            UNION
            SELECT 'a', TO_DATE ('02/01/2012', 'mm/dd/yyyy'), 24 FROM DUAL
            UNION
            SELECT 'a', TO_DATE ('06/01/2013', 'mm/dd/yyyy'), 12 FROM DUAL
            UNION
            SELECT 'a', TO_DATE ('07/01/2013', 'mm/dd/yyyy'), 56 FROM DUAL
            UNION
            SELECT 'b', TO_DATE ('01/01/2009', 'mm/dd/yyyy'), 34 FROM DUAL
            UNION
            SELECT 'b', TO_DATE ('03/01/2009', 'mm/dd/yyyy'), 78 FROM DUAL)
SELECT chosen.id, chosen.dt, SUM (lookback.val)/12
  FROM DateTable chosen, DateTable lookback
 WHERE   chosen.id = 'a' --your input id
         AND chosen.dt = TO_DATE ('07/01/2013', 'mm/dd/yyyy') --your input date
         AND chosen.id = lookback.id
         AND lookback.dt > ADD_MONTHS (chosen.dt, -12)
         AND lookback.dt <= chosen.dt
GROUP BY chosen.id, chosen.dt;

また、どの行にも存在しない日付/月に対してクエリを実行する場合は、次のようにします。

WITH DateTable
      AS (SELECT 'a' id, TO_DATE ('01/01/2012', 'mm/dd/yyyy') dt, 23 val FROM DUAL
            UNION
            SELECT 'a', TO_DATE ('1/1/2012', 'mm/dd/yyyy'), 23 FROM DUAL
            UNION
            SELECT 'a', TO_DATE ('02/01/2012', 'mm/dd/yyyy'), 24 FROM DUAL
            UNION
            SELECT 'a', TO_DATE ('06/01/2013', 'mm/dd/yyyy'), 12 FROM DUAL
            UNION
            SELECT 'a', TO_DATE ('07/01/2013', 'mm/dd/yyyy'), 56 FROM DUAL
            UNION
            SELECT 'b', TO_DATE ('01/01/2009', 'mm/dd/yyyy'), 34 FROM DUAL
            UNION
            SELECT 'b', TO_DATE ('03/01/2009', 'mm/dd/yyyy'), 78 FROM DUAL),
     InputData
      AS (SELECT 'b' id, TO_DATE ('12/15/2009', 'mm/dd/yyyy') dt FROM DUAL)
SELECT InputData.id, InputData.dt, SUM (lookback.val)/12
  FROM DateTable lookback, InputData
 WHERE  lookback.id = InputData.id
    AND lookback.dt > ADD_MONTHS (InputData.DT, -12)
    AND lookback.dt <= InputData.DT
     GROUP BY InputData.id, InputData.dt;
于 2013-08-01T20:39:58.943 に答える