AS
列のエイリアスを作成する場合はオプションですが、サブクエリを含むテーブルのエイリアスを作成する場合、Oracleではまったく許可されていません。AS
したがって、サブクエリに名前を付けます。キーワードは含めないでください。
FROM "Dat_ScheduledEvent" alias1
RIGHT OUTER JOIN (
SELECT "Dts"
FROM TABLE("F_GetDateIntervalTable"("In_OccurredTo", "In_OccurredFrom",
"In_Interval"))
) alias2
しかし、他にもいくつか問題があります。まず、二重引用符で囲む必要のある識別子を使用してオブジェクトを作成するのは面倒です。大文字と小文字が混在する識別子を持つことは本当に価値がありますか?第二に、それは派生フィールドにすぎないように見えEventDts
、列エイリアスは句以外のクエリでは使用できないorder by
ため、おそらくそのサブクエリも作成する必要があります。つまり、これも使用できますgroup by
。 。第三に、DATEDIFF
これは組み込みのOracle関数ではありません。自分で作成した場合を除き、他の何かを使用する必要があります。
SELECT
COUNT(alias1."Id") AS "ProcessedEvents",
alias1."EventDts"
FROM (
SELECT "Id",
TO_TIMESTAMP('1900-01-01 00:00:00.000000', 'YYYY-MM-DD HH24:MI:SS.FF')
+ NUMTODSINTERVAL(FLOOR(DATEDIFF('MI', '1900-01-01', "ProcessedDate")
/"In_Interval")*"In_Interval", 'MINUTE') AS "EventDts"
FROM "Dat_ScheduledEvent"
WHERE "ProcessedDate" BETWEEN "In_OccurredFrom" AND "In_OccurredTo"
) alias1
RIGHT OUTER JOIN (
SELECT "Dts"
FROM TABLE("F_GetDateIntervalTable"("In_OccurredTo", "In_OccurredFrom",
"In_Interval"))
) alias2
ON alias1."EventDts" = alias2."Dts"
GROUP BY alias2."EventDts";
DATEDIFF
まだ交換する必要がありますが、何をしているのかよくわかりません。が適切な間隔を生成している場合、F_GetDateIntervalTable
なぜそれを行う必要があるのかわかりません。ProcessedDate
間隔内の値、つまり>=
Dt and <
Dtを見つけたくないです+ InInterval
か?InInterval
もちろん、実際に何を表しているかに応じて。
F_GetDateIntervalTable
関心のある期間内の各間隔の開始を提供すると仮定すると、代わりに次のようなことを行うことができます。
PROCEDURE "GetProcessedEvents"
(
"In_OccurredFrom" TIMESTAMP,
"In_OccurredTo" TIMESTAMP,
"In_Interval" DECIMAL,
"Out_Cursor" OUT "Ref_Cursor"
)
IS
BEGIN
OPEN "Out_Cursor" FOR
SELECT
COUNT(Event."Id") AS "ProcessedEvents",
DateInt."Dts"
FROM (
SELECT "Dts", COALESCE(LEAD("Dts")
OVER (ORDER BY "Dts"), "In_OccurredTo") as "NextDts"
FROM TABLE("F_GetDateIntervalTable"("In_OccurredTo", "In_OccurredFrom",
"In_Interval"))
) DateInt
LEFT JOIN "Dat_ScheduledEvent" Event
ON Event."ProcessedDate" >= DateInt."Dts"
AND Event."ProcessedDate" < DateInt."NextDts"
GROUP BY DateInt."Dts"
ORDER BY DateInt."Dts";
END "GetProcessedEvents";
/
を使用LEAD()
すると、次の結果を確認できるため、サブクエリはタイムスタンプのリストを開始タイムスタンプと終了タイムスタンプのリストに変換します(最後のタイムスタンプはで終わりIn_OccurredTo
ます)。これにより、データテーブルで一致するレコードを検索できます。これらの範囲内にあります-の操作ProcessedDate
は必要ありません。
いくつかの偽のデータを使用して:
create table "Dat_ScheduledEvent" ("Id" number, "ProcessedDate" timestamp);
insert into "Dat_ScheduledEvent" ("Id", "ProcessedDate")
values (1, to_timestamp('2013-02-06 09:45', 'YYYY-MM-DD HH24:MI'));
insert into "Dat_ScheduledEvent" ("Id", "ProcessedDate")
values (1, to_timestamp('2013-02-06 09:50', 'YYYY-MM-DD HH24:MI'));
insert into "Dat_ScheduledEvent" ("Id", "ProcessedDate")
values (1, to_timestamp('2013-02-06 10:15', 'YYYY-MM-DD HH24:MI'));
...そしてSQL*Plusからプロシージャを呼び出す:
var r refcursor;
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI';
exec "GetProcessedEvents"(to_date('2013-02-06 08:00'), to_date('2013-02-06 12:00'), 1/24, :r);
print :r
...私は得る:
ProcessedEvents Dts
---------------------- -------------------------
0 06-FEB-13 08.00.00.000000000
2 06-FEB-13 09.00.00.000000000
1 06-FEB-13 10.00.00.000000000
0 06-FEB-13 11.00.00.000000000