Sql Oracle-按日期连接两个表,其中一个是每日表,另一个是每月表

Sql Oracle-按日期连接两个表,其中一个是每日表,另一个是每月表,sql,oracle,join,Sql,Oracle,Join,假设我的oracle数据库中有两个表,一个表包含月度数据,另一个表包含每日数据和列,例如,如下所示: DlyDateCol: DlyMatchingCol: DlyCol3: DlyCol4: MonCol3: MonCol4: 01-15-2014 a DlyVal3c DlyVal4c MonVal3c MonVal4c 01-15-2014 b DlyVal3d Dly

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

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     
...
TBL每月数据:

TblDailyData:

我有以下疑问:

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
现在,这个查询非常有效,但现在我需要扩展它,这样我就可以一次提取多天的数据,所以不再只针对2014年1月14日,而是针对2014年1月15日至2014年2月10日

该查询的结果如下所示:

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     
...
因此,基本上,每日数据每天都会变化,但每月数据会随着月份的变化而变化

我希望这是有道理的

非常感谢你的帮助

试试这个-

SQL Fiddle于2014年2月16日在此处更新:


在反复尝试之后,我想出了一个非常有效的解决方案——在这里发布,以防其他人有类似的问题:

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。你能提供一些样本数据和期望的结果吗?如果你每天都有条件。DlyMatchingCol=Monthly.MonMatchingCol,为什么你需要子查询选择Monthly.MonDateCol?GordonLinoff,我添加了假样本数据-我为之前没有这样做而道歉,打字太多了,我希望自己能解释清楚。。。我希望这是有意义的…基本上,我想从daily表中获取每日数据,每月数据将每天重复,直到一个新的月份出现在monthly表中…上面通过with子句使用您的示例的SQL FIDLE在这里:非常感谢您提出此解决方案,对于缺少示例数据,我深表歉意。但我觉得我只是表达了自己的错误。我现在用样本数据更新了这个问题-基本上,我想从daily表中获取每日数据,每月数据将每天重复,直到一个新的月份出现在monthly表中-我希望这现在是有意义的!!我想我明白了,我只做了2次编辑,确保这是最后一次尝试,我忘记了子查询中的连接。如果可以的话,我会在sqlfiddle中试用,但我想我会给你测试一下,以防你更快地使用它。非常感谢你在这个ShWiVeL上所做的工作-你发布的SQL Fiddle似乎只从每月的1/31数据中提取数据,尽管这两个月都是如此,而1月份的结果应该是12/31。。。。有什么想法吗?对不起,约翰,当我写这篇文章来检查这一点时,我实际上添加了mondatecol,但一定是对这一事实漠不关心,我离开了几天。我更改了用于获取mondatecol的子查询,它看起来将在需要时获得12/31和1/31。我在这里更新了sql fiddle:希望这对你有用。在我回答之前没有看到这一点:/看起来也可以。当我最初编写它时,我没有看到每月日期列是您的每日表上的前一个月的月末。我认为1/15和1/16等会在1/31的月表上滚动到一行,因为它们是在一月。
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     
...
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'
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