3

PLSQLを使用した2種類の小計に関するアドバイスを探しています。

1) 一意の人数、および 2) 総クレジット数を経時的に合計したデータ セットを取得する必要があります。

生データ:
これはトランザクション データです。学生が登録またはコースを登録するたびに、日付、学生 ID、およびクレジット (コース番号およびその他の関連データの束と共に) を含むレコードが挿入されます。学生ごとにコースごとに 1 つのレコード。

STUDENT_ID   CREDITS   DATE
1            3         01-JAN-12
1            2         02-JAN-12
57           1         03-JAN-12
1            1         03-JAN-12

処理済みデータ:
これは上司が確認する必要があるものです。これは後でトレンド分析に使用されます (たとえば、今年の 1 月 1 日が昨年の 1 月 1 日と比較してどのように測定されているかなどを確認するため)。

UniqueHeadcount   SumCredits   Date
1                 3            01-JAN-12
1                 5            02-JAN-12
2                 7            03-JAN-12

これに対する強引なアプローチは、個別の SELECT を (毎日 1 つ) まとめて記述し、それらを UNION することです。例えば:

SELECT
  COUNT(DISTINCT STUDENT_ID) as "UniqueHeadcount",
  SUM(CREDIT_HR) as "SumCredits",
  '01-JAN-12' as "DATE"
FROM
  REGISTRATIONS
WHERE
  TO_CHAR(DATE,'yyyymmdd') <= '20120101' 
GROUP BY
  '01-JAN-12'

UNION

SELECT
  COUNT(DISTINCT STUDENT_ID) as "UniqueHeadcount",
  SUM(CREDIT_HR) as "SumCredits",
  '02-JAN-12' as "DATE"
FROM
  REGISTRATIONS
WHERE
  TO_CHAR(DATE,'yyyymmdd') <= '20120102' 
GROUP BY
  '02-JAN-12'

UNION

...

結果は正確ですが、ご覧のとおり、これは洗練されたものとは言えません。365 日間それを行う必要がある場合は、まあ…野獣です。もっと良い方法があるはずです。

これまでの検索で、次のように使用できる「OVER」句について学びました。

SELECT
  COUNT(DISTINCT STUDENT_ID) OVER(ORDER BY TRUNC(RSTS_DATE) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) "UniqueHeadcount",
  SUM(CREDIT_HR) OVER(ORDER BY TRUNC(RSTS_DATE) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as "SumCredits",
  TRUNC(RSTS_DATE) as "DATE"
FROM
  REGISTRATIONS

このクエリはかなり短いですが (yay)、2 つの重大な問題があり、まだ解決策を見つけることができません。1 つ目は、COUNT DISTINCT では (設計上、明らかに?) 機能しないことです。そのため、しばらくコメントアウトしますが、2 つ目の問題が発生します。つまり、TRUNC() 関数が無視されます。RSTS_DATE は、SELECT を実行すると単なる日/月/年の値のように見えますが、実際には時刻も保持しているため、取得した結果セットは単純に日付だけでなく時間も合計されます --そのため、処理されたデータは、1 日に 1 つのレコードではなく、1 日に数百のレコードを返します (個々のコース登録ごとに 1 つ)。例えば:

UniqueHeadcount   SumCredits   Date
1                 3            01-JAN-12
1                 5            02-JAN-12
2                 6            03-JAN-12 (hidden time: 07:32:27)
2                 7            03-JAN-12 (hidden time: 08:01:33)

私が求めているものではありません。

だから私は専門知識を探しています-これまでに説明したことが理にかなっている場合-OVER句を使用する別の方法はありますか、またはおそらくこれに使用する必要があるPLSQLの別の機能があるかもしれませんか? わからない場合は、私は PLSQL に強くありませんが、誰かが私に方向性を与えることができれば、Google への言葉だけでも、助けていただければ幸いです。

ありがとう

4

1 に答える 1

1

これを試して:

WITH CRdata AS
(
    SELECT COUNT(DISTINCT STUDENT_ID) AS UniqueHeadcount,
    SUM(CREDIT_HR)                     AS SumCredits,
    TRUNC(RSTS_DATE) RSTS_DATE
     FROM REGISTRATIONS
    GROUP BY TRUNC(RSTS_DATE)
)
 SELECT SUM(UniqueHeadcount) OVER(ORDER BY RSTS_DATE ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS UniqueHeadcount,
  SUM(SumCredits) OVER(ORDER BY RSTS_DATE ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS  SumCredits, 
  RSTS_DATE 
  FROM CRdata
于 2012-07-09T18:33:11.753 に答える