Oracle - 按日期加入2个表,其中一个是每日,一个是每月

时间:2014-02-13 20:40:25

标签: sql oracle join

假设我的oracle数据库中有2个表 - 一个包含月度数据,另一个包含每日数据列,例如,如下所示:

TblMonthlyData:

MonMatchingCol:   MonDateCol:    MonCol3:     MonCol4:
a                 01-31-2014     MonVal3a     MonVal4a
b                 01-31-2014     MonVal3b     MonVal4b
a                 12-31-2013     MonVal3c     MonVal4c
b                 12-31-2013     MonVal3d     MonVal4d
a                 11-30-2013     MonVal3e     MonVal4e
b                 11-30-2013     MonVal3f     MonVal4f

TblDailyData:

DlyMatchingCol   DlyDateCol    DlyCol3    DlyCol4
a                01-14-2014    DlyVal3a   DlyVal4a 
b                01-14-2014    DlyVal3b   DlyVal4b 
a                01-15-2014    DlyVal3c   DlyVal4c 
b                01-15-2014    DlyVal3d   DlyVal4d 
a                01-16-2014    DlyVal3e   DlyVal4e 
b                01-16-2014    DlyVal3f   DlyVal4f 
 ...
a                02-01-2014    DlyVal3g   DlyVal4g 
b                02-01-2014    DlyVal3h   DlyVal4h 
a                02-02-2014    DlyVal3i   DlyVal4i 
b                02-02-2014    DlyVal3j   DlyVal4j 

我有以下问题:

SELECT 
  Daily.DlyDateCol, Daily.DlyMatchingCol, Daily.DlyCol3, Daily.DlyCol4, Monthly.MonCol3, Monthly.MonCol4
FROM 
  TblDailyData Daily, 
  TblMonthlyData Monthly
WHERE
    Daily.DlyDateCol = '01-14-2014'
  AND
    Monthly.MonDateCol = (SELECT MAX(MonDateCol) 
                          FROM TblMonthlyData 
                          WHERE TblMonthlyData.MonDateCol <= '01-14-2014')
  AND
    Daily.DlyMatchingCol = Monthly.MonMatchingCol

基本上,我每日表中都有每日数据,月表中有月度数据,他们有一列链接这两个数据,我希望得到最新的月度数据,直到我们从每日表。

因此,此查询的结果将是:

DlyDateCol:   DlyMatchingCol:   DlyCol3:   DlyCol4:   MonCol3:   MonCol4:
01-14-2014    a                 DlyVal3a   DlyVal4a   MonVal3c   MonVal4c     
01-14-2014    b                 DlyVal3b   DlyVal4b   MonVal3d   MonVal4d     

现在,此查询效果很好,但现在我需要对其进行扩展,以便我可以一次提取多天数据(因此不再仅仅用于01-14-2014,而是现在用于01-15-2014 to 02-10-2014 1}})?

该查询的结果如下所示:

DlyDateCol:   DlyMatchingCol:   DlyCol3:   DlyCol4:   MonCol3:   MonCol4:
01-15-2014    a                 DlyVal3c   DlyVal4c   MonVal3c   MonVal4c     
01-15-2014    b                 DlyVal3d   DlyVal4d   MonVal3d   MonVal4d     
01-16-2014    a                 DlyVal3e   DlyVal4e   MonVal3c   MonVal4c     
01-16-2014    b                 DlyVal3f   DlyVal4f   MonVal3d   MonVal4d     
...
02-01-2014    a                 DlyVal3g   DlyVal4g   MonVal3a   MonVal4a     
02-01-2014    b                 DlyVal3h   DlyVal4h   MonVal3b   MonVal4b     
02-02-2014    a                 DlyVal3i   DlyVal4i   MonVal3a   MonVal4a     
02-02-2014    b                 DlyVal3j   DlyVal4j   MonVal3b   MonVal4b     
...

因此,基本上,每日数据会每天都在变化,但月度数据会随着月份的变化而变化。

我希望这是有道理的。

非常感谢你的帮助!!!

2 个答案:

答案 0 :(得分:1)

试试这个 -

SQL Fiddle(2014年2月16日更新):http://sqlfiddle.com/#!4/d41d8/25423/0

select d.*, m.mondatecol, m.moncol3, m.moncol4
  from tbldailydata d
  join tblmonthlydata m
    on d.dlymatchingcol = m.monmatchingcol
 where m.mondatecol =
       (select max(x.mondatecol)
          from tblmonthlydata x
         where add_months(to_date(d.dlydatecol, 'MM-DD-YYYY'), -1) <=
               to_date(x.mondatecol, 'MM-DD-YYYY')
           and m.monmatchingcol = x.monmatchingcol)
   and d.dlydatecol between '01-15-2014' and '02-10-2014'

答案 1 :(得分:0)

在玩完之后,我想出了一个非常有效的解决方案 - 如果其他人遇到类似的问题,请将其放在这里:

SELECT 
  Daily.DlyDateCol, Daily.DlyMatchingCol, Daily.DlyCol3, Daily.DlyCol4, Monthly.MonCol3, Monthly.MonCol4
FROM 
  TblDailyData Daily, 
  TblMonthlyData Monthly
WHERE
    Daily.DlyDateCol BETWEEN '01-15-2014' AND '02-10-2014'
  AND
    Monthly.MonDateCol = (SELECT MAX(MonDateCol) 
                          FROM TblMonthlyData 
                          WHERE MonDateCol <= Daily.DlyDateCol)
  AND
    Daily.DlyMatchingCol = Monthly.MonMatchingCol

这里真正的诀窍就是简单地放入MonDateCol <= Daily.DlyDateCol - 这使得它们在每一行上都是相对的(如我所愿),因此日期正确地流过。

我希望这有意义并再次感谢你的帮助!!!!