ORACLE (11.2.0.1.0) - 带有日期表达式的递归 CTE

Ser*_*hov 5 sql oracle common-table-expression

以下问题的正确答案:

\n\n
    \n
  • 如果我没记错的话,这是一个在 11.2.0.3 或更高版本中修复的错误。(无论如何,11.2.0.1 不再受支持。11.2.0.4 是唯一仍受支持的 11.2 版本) \xe2\x80\x93 @a_horse_with_no_name
  • \n
  • Bug 编号为 11840579,已在 11.2.0.3 和 12.1.0.1\n\xe2\x80\x93 @a_horse_with_no_name 中修复
  • \n
\n\n

问题

\n\n

我有一张桌子

\n\n
CREATE TABLE test(\n  from_date date,\n  to_date date\n);\n\nINSERT INTO test(from_date,to_date)\n--VALUES(\'20171101\',\'20171115\');\nVALUES(TO_DATE(\'20171101\',\'YYYYMMDD\'),TO_DATE(\'20171115\',\'YYYYMMDD\'));\n
Run Code Online (Sandbox Code Playgroud)\n\n

Oracle 中的以下查询仅返回一行(预期 15 行)

\n\n
WITH dateCTE(from_date,to_date,d,i) AS(\n  SELECT from_date,to_date,from_date AS d,1 AS i\n  FROM test\n\n  UNION ALL\n\n  SELECT from_date,to_date,d+INTERVAL \'1\' DAY,i+1\n  FROM dateCTE\n  WHERE d<to_date\n)\nSELECT d,i\nFROM dateCTE\n
Run Code Online (Sandbox Code Playgroud)\n\n

SQL 小提琴 - http://sqlfiddle.com/#!4/36907/8

\n\n

为了测试我将条件更改为i<10

\n\n
WITH dateCTE(from_date,to_date,d,i) AS(\n  SELECT from_date,to_date,from_date AS d,1 AS i\n  FROM test\n\n  UNION ALL\n\n  SELECT from_date,to_date,d+INTERVAL \'1\' DAY,i+1\n  FROM dateCTE\n  --WHERE d<to_date\n  WHERE i<10 -- exit condition\n)\nSELECT d,i\nFROM dateCTE\n
Run Code Online (Sandbox Code Playgroud)\n\n

并得到下一个结果

\n\n
| D          | I  |\n|------------|----|\n| 2017-11-01 |  1 |\n| 2017-10-31 |  2 |\n| 2017-10-30 |  3 |\n| 2017-10-29 |  4 |\n| 2017-10-28 |  5 |\n| 2017-10-27 |  6 |\n| 2017-10-26 |  7 |\n| 2017-10-25 |  8 |\n| 2017-10-24 |  9 |\n| 2017-10-23 | 10 |\n
Run Code Online (Sandbox Code Playgroud)\n\n

为什么这个递归查询在 Oracle 中返回错误结果?

\n\n

SQL 小提琴 - http://sqlfiddle.com/#!4/36907/5

\n\n

我在 SQLServer 中运行了类似的查询,得到了正确的结果

\n\n
WITH dateCTE(from_date,to_date,d,i) AS(\n  SELECT from_date,to_date,from_date AS d,1 AS i\n  FROM test\n\n  UNION ALL\n\n  SELECT from_date,to_date,DATEADD(DAY,1,d),i+1\n  FROM dateCTE\n  WHERE d<to_date\n)\nSELECT d,i\nFROM dateCTE\n
Run Code Online (Sandbox Code Playgroud)\n\n

正确的结果

\n\n
d           i\n2017-11-01  1\n2017-11-02  2\n2017-11-03  3\n2017-11-04  4\n2017-11-05  5\n2017-11-06  6\n2017-11-07  7\n2017-11-08  8\n2017-11-09  9\n2017-11-10  10\n2017-11-11  11\n2017-11-12  12\n2017-11-13  13\n2017-11-14  14\n2017-11-15  15\n
Run Code Online (Sandbox Code Playgroud)\n\n

为什么它在 Oracle 中不起作用?您可以建议哪些替代方案?谢谢你!

\n\n

真实系统的屏幕截图:

\n\n

在此输入图像描述

\n\n

在此输入图像描述

\n\n

在此输入图像描述

\n

小智 2

如果您想要从日期到日期的顺序,请使用这样的选择:

SELECT  DATE '2017-11-01' + LEVEL - 1 AS D, LEVEL AS I
FROM DUAL
CONNECT BY LEVEL <= DATE '2017-11-15' - DATE '2017-11-01' + 1;
Run Code Online (Sandbox Code Playgroud)