【问题标题】:Pass min and max date from table to select query从表中传递最小和最大日期以选择查询
【发布时间】:2018-09-24 08:42:58
【问题描述】:

我需要填补日期之间的空白,所以我得到了这个 sql 查询:

select * from (
  SELECT null as ID, to_date('15/08/28', 'yy/mm/dd') + ROWNUM - 1 as DATE_OF_RATE, null as VALUE, null as CURRENCY_ID
  FROM dual
  CONNECT BY LEVEL <= to_date('15/09/05', 'yy/mm/dd') - to_date('15/08/28', 'yy/mm/dd') + 1
) empCur
left join CURRENCY_RATE cr on TRUNC(empCur.DATE_OF_RATE) = (cr.DATE_OF_RATE)
AND cr.currency_id = 4;

我需要从 currency_rate 表中传递 min 和 max date_of_rate 而不是上面的硬编码日期。所以我尝试了这个,但我得到了不同的结果:

select * from (
  SELECT null as ID, (select min(date_of_rate) from currency_rate) + ROWNUM - 1 as DATE_OF_RATE, null as VALUE, null as CURRENCY_ID
  FROM dual
  CONNECT BY LEVEL <= (select max(date_of_rate) - min(date_of_rate) + 1 from currency_rate)
) empCur
left join CURRENCY_RATE cr on TRUNC(empCur.DATE_OF_RATE) = (cr.DATE_OF_RATE)
where cr.date_of_rate between to_date('15/08/28', 'yy/mm/dd') and to_date('15/09/05', 'yy/mm/dd')
AND cr.currency_id = 4;

如您所见,这并没有填补日期范围之间的空白。有没有可能我想要实现的目标?

【问题讨论】:

  • 在您的第二个查询中,您在左连接表CURRENCY_RATE 上使用WHERE 条件,从而基本上击败了左连接并将其转变为内连接。将WHERE 替换为and,看看是否有帮助。

标签: sql oracle11g


【解决方案1】:

您的查询基本没问题。问题是where 子句。该条件应该在 first 表上:

select *
from (select  null as ID, (select min(date_of_rate) from currency_rate) + ROWNUM - 1 as DATE_OF_RATE, null as VALUE, null as CURRENCY_ID
      from dual
      connect by level <= (select max(date_of_rate) - min(date_of_rate) + 1 from currency_rate)
     ) empCur left join
     CURRENCY_RATE cr
     on empCur.DATE_OF_RATE = cr.DATE_OF_RATE and
        cr.currency_id = 4
where empCur.DATE_OF_RATE >= date '2015-08-28' and
      empCur.DATE_OF_RATE <= date '2015-09-05' ;

我不明白为什么需要TRUNC()。如果是,只需重新添加即可。

【讨论】:

  • 假设我的列 date_of_rate 在 2010-01-01 到 2018-01-01 的范围内。是否可以仅获取日期在 2015-08-28 和 2015-09-05 之间的行?当我执行您的查询时,我会从 2010-01-01 到 2015-08-27 以及后来从 2015-09-06 到 2018-01-01 得到到处都是空值的行。我的目标是查询日期范围而没有日期之间的间隔,所以我认为首先我需要填补整个表中的间隔,然后我将能够只查询指定日期范围之间的这些行。好的,编辑后现在我看到它完全按照我想要的方式工作! :)
【解决方案2】:

我发现使用临时变量会有所帮助。这就是我要做的。请注意我的语法可能很不稳定,因为我是从记忆中做的。不过,一些简单的谷歌搜索会让你走完剩下的路。

第 1 步。创建一些临时变量。这些需要在一个命令中运行。

DECLARE @MinDate DATETIME;
DECLARE @MaxDate DATETIME;

@MinDate = SELECT Min([DATE_OF_RATE]) FROM CURRENCY_RATE; 
@MaxDate = SELECT Max([DATE_OF_RATE]) FROM CURRENCY_RATE;

第 2 步。创建一个包含所有可能日期的日历表,将日期作为唯一列。如果需要,请手动执行此操作。在此系统不再使用之后,您始终可以创建一个日期最长为 2050 天的日历表。

第 3 步。在日期从日历表左连接到费率表。无论费率有多大差距,这都会给你一个行。

SELECT c.CalDate FROM Calendar c
LEFT JOIN CURRENCY_RATE cr
ON c.CalDate = cr.DATE_OF_RATE

步骤 4. 使用临时表过滤日期在最小/最大范围内的新表

SELECT c.CalDate FROM Calendar c
LEFT JOIN CURRENCY_RATE cr
ON c.CalDate = cr.DATE_OF_RATE
WHERE c.CalDate >= @MinDate AND c.CalDate <= @MaxDate

我希望这会有所帮助。

【讨论】:

  • 这对 Oracle 无效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
  • 2017-10-12
  • 2010-12-11
  • 2020-05-31
相关资源
最近更新 更多