从表中传递最小和最大日期以选择查询

时间:2018-09-24 08:42:59

标签: sql oracle11g

我需要填补日期之间的空白,所以我得到了这个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;

enter image description here 而不是上面的硬编码日期,我需要传递 currency_rate 表中的最小和最大 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;

enter image description here

如您所见,这并未填补日期范围之间的空白。我什至有可能实现?

2 个答案:

答案 0 :(得分: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()是必要的。如果是这样,只需将其重新添加。

答案 1 :(得分:0)

我发现使用临时变量可以有所帮助。这就是我要做的。请注意,因为我正在从内存中执行此操作,所以我的语法可能有些动摇。进行一些谷歌搜索可以让您省事。

步骤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步。创建一个包含所有可能日期的日历表,以字面意义上的date为唯一列。如果需要,请手动执行此操作。您始终可以创建一个日历表,该日历表的有效日期最多为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

我希望这会有所帮助。