我需要一些帮助来完成这个程序。问题是如何对不同的SELECT进行别名,以便我可以在RIGHT OUTER JOIN上匹配它们。传统的AS不起作用。有什么想法吗?
PROCEDURE "GetProcessedEvents"
(
"In_OccurredFrom" TIMESTAMP,
"In_OccurredTo" TIMESTAMP,
"In_Interval" DECIMAL,
"Out_Cursor" OUT "Ref_Cursor"
)
IS
BEGIN
OPEN "Out_Cursor" FOR
SELECT
COUNT("Id") AS "ProcessedEvents",
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"
RIGHT OUTER JOIN
(SELECT "Dts" FROM TABLE("F_GetDateIntervalTable"("In_OccurredTo", "In_OccurredFrom", "In_Interval")))
ON "EventDts" = "Dts"
WHERE
"ProcessedDate" BETWEEN "In_OccurredFrom" AND "In_OccurredTo"
GROUP BY
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');
END "GetProcessedEvents";
答案 0 :(得分:1)
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()
可以查看下一个结果,以便子查询将时间戳列表转换为from-和to-timestamps列表(最后一个结束于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
答案 1 :(得分:0)
是的,我有一些想法。
使用 WITH
子句可能很有用,它允许您将复杂的SELECT语句分解为子查询,从而有效地改进代码结构,当然,您可以通过别名引用它们(子查询)。
以下是您使用的一个小例子:
WITH subquery AS (SELECT sysdate FROM dual)
-- Here goes main query where subquery must be used
SELECT *
FROM subquery
OPEN "Out_Cursor" FOR
WITH Q AS (SELECT "Dts" FROM TABLE("F_GetDateIntervalTable"("In_OccurredTo", "In_OccurredFrom", "In_Interval")))
SELECT
COUNT("Id") AS "ProcessedEvents",
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"
RIGHT OUTER JOIN
Q
ON "EventDts" = "Dts"
WHERE
"ProcessedDate" BETWEEN "In_OccurredFrom" AND "In_OccurredTo"
GROUP BY
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');
END "GetProcessedEvents";
答案 2 :(得分:0)
尝试删除变量名称旁边的双引号,除非语法要求它们。这可能会让解析器感到困惑。