Oracle查询无限期运行

时间:2017-11-09 21:27:27

标签: sql oracle

我的查询有点无限期地运行,我可能会在这里进行圈子但是它不会给我一个错误,只是连续运行。

查询

WITH calendar AS (
  SELECT dt
  FROM (
    SELECT TRUNC(LAST_DAY(TO_DATE(&month || '/01/' || &year, 'MM/DD/YYYY')) - ROWNUM + 1) AS dt
    FROM DUAL CONNECT BY ROWNUM <= 31
  )
  WHERE dt >= TRUNC(TO_DATE(&month || '/01/' || &year, 'MM/DD/YYYY'), 'MM')
  ORDER BY dt ASC
)

SELECT
  cal.dt,
  (
    SELECT NVL(SUM(rd.rate_value), 0.00)
    FROM cage_dates cd
    LEFT JOIN cages c ON c.id = cd.cage_id
    LEFT JOIN rent_item ri ON ri.id = c.rent_item_id
    LEFT JOIN rate_dates rd ON rd.rent_item_id = c.rent_item_id
    WHERE c.group_id = 123
    AND c.room_id = 456
    AND (
      LOWER(c.cage_use) NOT IN ('created in error', 'prod setup')
      OR c.cage_use IS NULL
    )
    AND ri.display_name NOT LIKE '% BR'
    AND TRUNC(cd.added) <= cal.dt
    AND (
      CASE
        WHEN cd.removed IS NOT NULL AND TRUNC(cd.removed) >= cal.dt THEN 1
        WHEN cd.removed IS NULL THEN 1
        ELSE 0
      END = 1
    )
    AND TRUNC(rd.effective_on) <= cal.dt
    AND (
      CASE
        WHEN rd.effective_until IS NOT NULL AND TRUNC(rd.effective_until) >= cal.dt THEN 1
        WHEN rd.effective_until IS NULL THEN 1
        ELSE 0
      END = 1
    )
  ) AS per_diem
FROM calendar cal
ORDER BY cal.dt ASC

当我将cal.dt更改为TO_DATE('10/25/2017', 'MM/DD/YYYY')时,它会向我提供当天所有费率的正确总和,但会将其附加到所有日期:

dt          per_diem
--------------------
10/01/2017      1.19
10/02/2017      1.19
...
10/31/2017      1.19

虽然我想要类似的东西:

dt          per_diem
--------------------
10/01/2017         0
10/02/2017      1.19
10/03/2017      2.52
...
10/31/2017      0.67

有人有任何想法吗?

1 个答案:

答案 0 :(得分:2)

我会将子查询移动到连接中,如下所示:

WITH calendar AS (
  SELECT dt
  FROM (
    SELECT TRUNC(LAST_DAY(TO_DATE(&month || '/01/' || &year, 'MM/DD/YYYY')) - ROWNUM + 1) AS dt
    FROM DUAL CONNECT BY ROWNUM <= 31
  )
  WHERE dt >= TRUNC(TO_DATE(&month || '/01/' || &year, 'MM/DD/YYYY'), 'MM')
)
SELECT cal.dt, NVL(SUM(rd.rate_value), 0.00)
FROM Calendar cal
LEFT JOIN cage_dates cd ON TRUNC(cd.added) = cal.dt
LEFT JOIN cages c ON c.id = cd.cage_id
LEFT JOIN rent_item ri ON ri.id = c.rent_item_id
LEFT JOIN rate_dates rd ON rd.rent_item_id = c.rent_item_id
WHERE c.group_id = 123
AND c.room_id = 456
AND (
  LOWER(c.cage_use) NOT IN ('created in error', 'prod setup')
  OR c.cage_use IS NULL
)
AND ri.display_name NOT LIKE '% BR'
AND (
  CASE
    WHEN cd.removed IS NOT NULL AND TRUNC(cd.removed) >= cal.dt THEN 1
    WHEN cd.removed IS NULL THEN 1
    ELSE 0
  END = 1
)
AND TRUNC(rd.effective_on) <= cal.dt
AND (
  CASE
    WHEN rd.effective_until IS NOT NULL AND TRUNC(rd.effective_until) >= cal.dt THEN 1
    WHEN rd.effective_until IS NULL THEN 1
    ELSE 0
  END = 1
GROUP  BY cal.dt

但是我不确定你在TRUNC(cd.added) <= cal.dt开始尝试的是什么,一开始以为这是一个运行总和,但也许你想在每天都出现一个值?