在pl/sql中发现中断时的返回日期
我有一张三列的桌子在pl/sql中发现中断时的返回日期,sql,plsql,oracle-sqldeveloper,plsqldeveloper,Sql,Plsql,Oracle Sqldeveloper,Plsqldeveloper,我有一张三列的桌子 Position_id start_date end_date 10 01-JUN-05 31-DEC-2012 10 01-JAN-13 31-DEC-4712 现在我想检查一下,当开始日期是结束日期之后的1个日期时,我应该继续循环。与上述情况一样,起始日期“2013年1月1日”为2012年12月31日之后的1天。 因此,它应该返回开始日期“2005年6月1日” 但一旦出现如下例外情况:- Position_
Position_id start_date end_date
10 01-JUN-05 31-DEC-2012
10 01-JAN-13 31-DEC-4712
现在我想检查一下,当开始日期是结束日期之后的1个日期时,我应该继续循环。与上述情况一样,起始日期“2013年1月1日”为2012年12月31日之后的1天。
因此,它应该返回开始日期“2005年6月1日”
但一旦出现如下例外情况:-
Position_id start_date end_date
10 01-JUN-05 31-DEC-2012
10 01-FEB-13 31-DEC-4712
与本例一样,开始日期不是2012年12月31日结束日期之后的1个日期。
因此,它应该返回开始日期“2013年2月1日”
为此,我做了一个函数。。但我不知道如何使用和返回日期
create or replace
FUNCTION XX_test_RATING_FUNC(P_PERSON_ID NUMBER)
RETURN VARCHAR2
AS
V_PERSON_ID VARCHAR2(100);
V_POS VARCHAR2(110);
V_RATE VARCHAR2(100);
V_POS_DT DATE;
/**Cursor to fetch date when a position was attached with an employee **/
CURSOR CUR_POS_st_date
is
SELECT (EFFECTIVE_START_DATE),to_char(effective_end_date,'DD-MON-YYYY')
FROM tablePAAF
order by desc;
CURSOR CUR_POS
IS
SELECT COUNT(DISTINCT position_id ) from table;
BEGIN
OPEN CUR_POS_ST_DATE;
FETCH CUR_POS_st_date INTO V_POS_dt;
CLOSE CUR_POS_ST_DATE;
OPEN CUR_POS_ST_DATE;
FETCH CUR_POS_ST_DATE INTO V_PERSON_ID;
CLOSE CUR_POS_ST_DATE;
V_DT DATE ;
DBMS_OUTPUT.PUT_LINE(V_POS_DT||'V_PERSON_ID');
FOR I IN 1..V_PERSON_ID
LOOP
V_DT := I.EFFECTIVE_START_DATE;
if v_dt=i.effective_end_date
then
//关于这一部分的困惑//
else
Break
-- END;
EXCEPTION WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE('Error'||SQLERRM);
RETURN 'ERROR';
END XX_test_RATING_FUNC;
我只需要for循环部分的帮助。不知道如何摆弄日期你能使用窗口功能吗?以您的第二个示例为例,为了达到这个目的,使用位置_id 11可以通过基于集合的编辑方式来解决这个问题:最好说非迭代方式,而不需要使用函数或游标 通过选择开始日期等于结束日期后一天的任何记录递归遍历表,然后可以将每个位置id的最大排名作为最终答案
;
WITH cte ( RID, Position_id, start_date, end_date ) AS (
SELECT ROW_NUMBER() OVER (
PARTITION BY Position_id
ORDER BY start_date ) RID,
Position_id, start_date, end_date
FROM tablePAAF
UNION ALL
SELECT b.RID + 1, a.Position_id, a.start_date, b.end_date
FROM tablePAAF a
INNER JOIN cte b
ON a.Position_id = b.Position_id
AND a.end_date = b.start_date - INTERVAL '1' DAY )
SELECT p.Position_id, p.start_date, p.end_date
FROM ( SELECT Position_id, MAX( RID ) RID
FROM cte
GROUP BY Position_id ) mpr
LEFT JOIN cte p
ON mpr.Position_id = p.Position_id
AND mpr.RID = p.RID
ORDER BY p.Position_id;
把这里发生的事情分解一下,我们将看一下CTE的第一部分,你可以把它看作是一个特别的视图,实际上,或者像Oracle行话中所说的那样,递归子查询分解。在这里,我们看到,行编号如何给每一行一个等级,从分区中每个位置的一个等级开始,并在每个后续的开始日期之前增加该等级
导致:
╔═════╦═════════════╦═════════════════════════════════╦═════════════════════════════════╗
║ RID ║ POSITION_ID ║ START_DATE ║ END_DATE ║
╠═════╬═════════════╬═════════════════════════════════╬═════════════════════════════════╣
║ 1 ║ 10 ║ June, 01 2005 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
║ 2 ║ 10 ║ January, 01 2013 00:00:00+0000 ║ December, 31 4712 00:00:00+0000 ║
║ 1 ║ 11 ║ June, 01 2005 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
║ 2 ║ 11 ║ February, 01 2013 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
╚═════╩═════════════╩═════════════════════════════════╩═════════════════════════════════╝
从这里,我们添加了我们的CTE。这个附加的SELECT获取tablePAAF中的数据,并将其连接到我们新创建的CTE,条件是对于特定的位置id,记录的结束日期等于CTE中记录的开始日期的一天,这创建了一种返回时间递归。为了计算日期,我们使用INTERVAL关键字和'1'DAY,让Oracle知道我们想减去一天进行比较。因为我们感兴趣的是创建第一个开始日期和最后一个结束日期的记录,所以我们选择保留加入的CTE记录的结束日期的值,并从原始数据位置获取新的开始日期。这个新记录的排名然后增加1。只有一条这样的记录被找到,因此我们得到以下结果:
╔═════╦═════════════╦═════════════════════════════════╦═════════════════════════════════╗
║ RID ║ POSITION_ID ║ START_DATE ║ END_DATE ║
╠═════╬═════════════╬═════════════════════════════════╬═════════════════════════════════╣
║ 1 ║ 10 ║ June, 01 2005 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
║ 2 ║ 10 ║ January, 01 2013 00:00:00+0000 ║ December, 31 4712 00:00:00+0000 ║
║ 1 ║ 11 ║ June, 01 2005 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
║ 2 ║ 11 ║ February, 01 2013 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
║ 3 ║ 10 ║ June, 01 2005 00:00:00+0000 ║ December, 31 4712 00:00:00+0000 ║
╚═════╩═════════════╩═════════════════════════════════╩═════════════════════════════════╝
有了这个结果集,我们所需要做的就是获得每个职位id的最大排名,让我们回到原来的位置 为什么第二个示例中应采用2013年2月1日?你们认为它有更进一步的线吗?这是两个例子。。。当我运行查询时,这些结果中的任何一个都可能出现,我无法理解您的逻辑。什么是cte?是因为我的测试用例数据的二月结束日期不正确,还是查询没有按照您的预期进行?查询没有返回我预期的结果。。。我找不到漏洞。。。。很简单,如果n其他人会做i gues。。。。
╔═════╦═════════════╦═════════════════════════════════╦═════════════════════════════════╗
║ RID ║ POSITION_ID ║ START_DATE ║ END_DATE ║
╠═════╬═════════════╬═════════════════════════════════╬═════════════════════════════════╣
║ 1 ║ 10 ║ June, 01 2005 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
║ 2 ║ 10 ║ January, 01 2013 00:00:00+0000 ║ December, 31 4712 00:00:00+0000 ║
║ 1 ║ 11 ║ June, 01 2005 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
║ 2 ║ 11 ║ February, 01 2013 00:00:00+0000 ║ December, 31 2012 00:00:00+0000 ║
║ 3 ║ 10 ║ June, 01 2005 00:00:00+0000 ║ December, 31 4712 00:00:00+0000 ║
╚═════╩═════════════╩═════════════════════════════════╩═════════════════════════════════╝