oracle sql - 缺少范围的日期

时间:2014-10-28 17:38:41

标签: sql oracle

我创建了以下脚本......

SELECT
  gr.RESERVATION_NO,
  gr.TITLE,
  gr.CATNR,
  gl.DUEDATE,
  gr.CRE_USR,
  gl.QTY,
  gl.WORK_CENTER_NO,
  gl.TEC_CRITERIA,
  gr.RESERVE_QTY,
  gl.PLANT,
  studate.dt
FROM GPS_RESERVATION gr, 
    (Select first_date + Level-1 dt 
    From
    (
        Select trunc(sysdate) first_date,
        trunc(sysdate)+60 last_date
        from dual
    )
        Connect By Level <= (last_date - first_date) +1 ) studate
  INNER JOIN GPS_RESERVATION_LOAD gl
          ON gl.work_center_no = 'ALIN'
         AND gl.duedate = studate.dt
         AND gl.plant = 'W'
WHERE gr.RESERVATION_NO = gl.RESERVATION_NO
  AND gr.ACTIVE_FLAG  =  'Y'
  AND gr.reservation_no = '176601'
ORDER BY 
  gl.DUEDATE

我希望看到从sysdate到sysdate + 60的所有日期,但是,我只能获得duedate存在的日期。

我明白了......

enter image description here

我期待......

enter image description here

我做错了什么?

感谢您的帮助。

1 个答案:

答案 0 :(得分:3)

您正在将较旧的Oracle连接语法与较新的ANSI连接语法混合使用,这有点令人困惑,并且可能会使优化器绊倒;但主要问题是你在生成的日期列表和gl表之间有一个内连接;然后,您在where子句中也有一个连接条件,即使您更改了连接类型,也会将其保持为内连接。

没有表格结构或任何数据,我想你想要:

...
FROM (
    Select first_date + Level-1 dt 
    From
    (
        Select trunc(sysdate) first_date,
        trunc(sysdate)+60 last_date
        from dual
    )
    Connect By Level <= (last_date - first_date) +1
  ) studate
  CROSS JOIN GPS_RESERVATION gr
  LEFT OUTER JOIN GPS_RESERVATION_LOAD gl
          ON gl.work_center_no = 'ALIN'
         AND gl.duedate = studate.dt
         AND gl.plant = 'W'
         AND gl.RESERVATION_NO = gr.RESERVATION_NO
WHERE gr.ACTIVE_FLAG = 'Y'
  AND gr.reservation_no = '176601'
ORDER BY 
  gl.DUEDATE

交叉连接为您提供生成日期的笛卡尔积和gr中的匹配记录;因此,如果您的gr过滤条找到5行,那么您将获得该加入的300个结果。然后左外连接在gl中查找任何匹配的行,其中所有过滤/连接条件与gl子句中的on相关。

您应该查看查询的执行计划和这个,首先要看看差异,但更重要的是要检查它是否正如您所期望的那样以合理且经济有效的方式加入和过滤。当然,检查结果是否正确...您可能还想查看使用左外连接但保留原始where子句的版本,并查看它使其返回到内连接