是否可以编写一个查询,返回两个指定日期之间每天的日期?

发布于 2024-08-27 17:37:25 字数 206 浏览 9 评论 0原文

基本上,问题说明了一切。我需要一个 PL\SQL 查询,它返回两个日期之间的日期列表,这样对于 2010 年 1 月 1 日到 2010 年 1 月 20 日,我将返回 20 行:

the_date 
--------
01-JAN-2010
02-JAN-2010
03-JAN-2010
04-JAN-2010
...
20-JAN-2010

Basically, the question says it all. I need a PL\SQL query that returns a list of dates between two dates such that for 01-JAN-2010 to 20-JAN-2010 I would get 20 rows returned:

the_date 
--------
01-JAN-2010
02-JAN-2010
03-JAN-2010
04-JAN-2010
...
20-JAN-2010

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅黛梨妆こ 2024-09-03 17:37:25

以下查询将返回 1/1 到 1/20(含)之间的每一天。

    select to_date('1/1/2010','mm/dd/yyyy')+level
      from dual
connect by level <= to_date('1/20/2010','mm/dd/yyyy')
                    - to_date('1/1/2010','mm/dd/yyyy');

The following query will return each day between 1/1 and 1/20 (inclusive).

    select to_date('1/1/2010','mm/dd/yyyy')+level
      from dual
connect by level <= to_date('1/20/2010','mm/dd/yyyy')
                    - to_date('1/1/2010','mm/dd/yyyy');
锦爱 2024-09-03 17:37:25

这是来自 postgres 的示例,我希望方言在递归方面具有可比性

WITH RECURSIVE t(n) AS (
    VALUES (1)
  UNION ALL
    SELECT n+1 FROM t WHERE n < 20
)
SELECT n FROM t;

...将返回 20 条记录,数字从 1 到 20
将它们转换/转换为日期,然后您就可以

更新:
抱歉,这里没有ORA,但是根据这篇文章

SELECT
   SYS_CONNECT_BY_PATH(DUMMY, '/')
FROM
   DUAL
CONNECT BY
   LEVEL<4;

给出了

SYS_CONNECT_BY_PATH(DUMMY,'/')
--------------------------------
/X
/X/X
/X/X/X

它也是表示这应该是生成行的非常有效的方法。
如果在上面的选择中可以使用 ROWNUM 并且如果在 LEVEL 条件中可以使用变量,则可以得出解决方案。

UPDATE2:

确实有几个选项

SELECT (CAST('01-JAN-2010' AS DATE) + (ROWNUM - 1)) n
FROM   ( SELECT 1 just_a_column
         FROM   dual
         CONNECT BY LEVEL <= 20
       )

orafaq 指出:“应该指出的是,在 Oracle 的更高版本中,至少早到 10gR1,针对 Dual 的操作已经过优化,因此它们不需要逻辑或物理 I/O 操作。这使得它们速度相当快。”,所以我想说这并不完全深奥。

Here's an example from postgres, I hope the dialects are comparable in regards to recursive

WITH RECURSIVE t(n) AS (
    VALUES (1)
  UNION ALL
    SELECT n+1 FROM t WHERE n < 20
)
SELECT n FROM t;

...will return 20 records, numbers from 1 to 20
Cast/convert these to dates and there you are

UPDATE:
Sorry, don't have ORA here, but according to this article

SELECT
   SYS_CONNECT_BY_PATH(DUMMY, '/')
FROM
   DUAL
CONNECT BY
   LEVEL<4;

gives

SYS_CONNECT_BY_PATH(DUMMY,'/')
--------------------------------
/X
/X/X
/X/X/X

It is also stated that this is supposed to be very efficient way to generate rows.
If ROWNUM can be used in the above select and if variable can be used in LEVEL condition then solution can be worked out.

UPDATE2:

And indeed there are several options.

SELECT (CAST('01-JAN-2010' AS DATE) + (ROWNUM - 1)) n
FROM   ( SELECT 1 just_a_column
         FROM   dual
         CONNECT BY LEVEL <= 20
       )

orafaq states that: 'It should be noted that in later versions of oracle, at least as far back as 10gR1, operations against dual are optimized such that they require no logical or physical I/O operations. This makes them quite fast.', so I would say this is not completely esoteric.

终止放荡 2024-09-03 17:37:25

好吧,这可能看起来有点老套,但这就是我的想法:

SELECT (CAST('01-JAN-2010' AS DATE) + (ROWNUM - 1)) AS the_date
FROM all_objects
WHERE ROWNUM <= CAST('20-JAN-2010' AS DATE) - CAST('01-JAN-2010' AS DATE) + 1

神奇的酱汁是使用 ROWNUM 作为日期算术的种子,我使用 all_objects 但您可以使用任何具有足够行数的表来提供所需的范围。您可以对其进行洗牌以使其在 SYSDATE 下工作,而不是对值进行硬编码,但原则上我认为这个想法是合理的。

下面是一个返回 10 天前到 10 天时间之间的日期列表的示例:

SELECT (SYSDATE -10 + (ROWNUM-1)) AS the_date
FROM all_objects
WHERE ROWNUM <= (SYSDATE +10) - (SYSDATE -10) + 1

OK, so it might seem a little hacky, but here's what I've come up with:

SELECT (CAST('01-JAN-2010' AS DATE) + (ROWNUM - 1)) AS the_date
FROM all_objects
WHERE ROWNUM <= CAST('20-JAN-2010' AS DATE) - CAST('01-JAN-2010' AS DATE) + 1

The magic sauce is using ROWNUM as a seed for date arithmetic, I'm using all_objects but you could use any table that has enough rows in it to supply the required range. You can shuffle it around to make it work off SYSDATE instead of hard coding the value, but in principle I think that the idea is sound.

Here's an example that returns a list of dates from 10 days ago to 10 days time:

SELECT (SYSDATE -10 + (ROWNUM-1)) AS the_date
FROM all_objects
WHERE ROWNUM <= (SYSDATE +10) - (SYSDATE -10) + 1
简美 2024-09-03 17:37:25

不可以。查询只能返回现有数据 - 如果您没有所有日期的表,那么您就出局了。

也就是说(我不是预言机专家),函数或存储过程应该能够做到这一点。在 SQL Server 中,我将有一个返回表的函数(然后我可以在联接中使用该表)。

但纯粹的询问——不。除非oracle已经有这样的功能了。

No. Queries can only return existing data - and if you have no table of all days, you are out.

That said (I am no oracle specialist), a function or stored procedure should be able to do that. In SQL Server I would have a function returning a table (that I could then use in joins).

But a pure query - no. Not unless oracle has such a function already.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文