如何在Oracle Select语句中设置会计年度

时间:2016-07-27 18:41:59

标签: oracle oracle10g oracle-sqldeveloper

我正在尝试将T_SQL查询转换为oracle查询以获取会计年度的信息;这对我来说从10月1日到9月30日运行这是我想要使用的但是收到错误消息“第1行的无效SQL语句

var FromDate date
IF extract(month from sysdate) BETWEEN 10 AND 12
exec :FromDate := (extract(month from sysdate), 10, 1) ELSE
exec :FromDate := (extract(year from sysdate)) - 1, 10, 1)
                         SELECT        COUNT(DISTINCT [CSMAST].[CM_CALL])
                          FROM            [TIBURON].[CSMAST] [CSMAST] JOIN
                                                   [TIBURON].[SSCTAB] [SSCTAB] ON ([CSMAST].[CM_DID_1] = [SSCTAB].[RC_KEY])
                          WHERE        [CSMAST].[CM_DATE] >= @FromDate AND [SSCTAB].[RC_TYPE] = 'O*

非常感谢任何帮助

1 个答案:

答案 0 :(得分:1)

IF不是SQL构造,您在PL / SQL块之外使用它,因此您正在使用的客户端正确告诉您它无法识别它。您可能不想使用PL / SQL,因为您可以在不将生成日期作为绑定变量生成的情况下单独执行。

如果我了解您尝试做的事情,您可以在查询中使用案例表达式来决定日期范围,例如:

SELECT COUNT(DISTINCT CSMAST.CM_CALL)
FROM TIBURON.CSMAST
JOIN TIBURON.SSCTAB ON CSMAST.CM_DID_1 = SSCTAB.RC_KEY
WHERE CSMAST.CM_DATE >=
  CASE WHEN extract(month from sysdate) BETWEEN 10 AND 12 THEN
    -- get start of current year, add 9 months to get this October
    ADD_MONTHS(TRUNC(sysdate, 'YYYY'), 9)
  ELSE
    -- get start of current year, subtract 3 months to get previous October
    ADD_MONTHS(TRUNC(sysdate, 'YYYY'), -3)
  END
AND SSCTAB.RC_TYPE = 'O*'

不确定最后一行是否应该是通配符;如果是这样的话:

AND SSCTAB.RC_TYPE LIKE 'O%'

您可以通过虚拟查询查看案例表达式生成的日期:

WITH t (dt) AS (
  SELECT add_months(SYSDATE, 6-LEVEL) FROM dual CONNECT BY LEVEL <= 27
)
SELECT dt,
  CASE WHEN EXTRACT(MONTH FROM dt) BETWEEN 10 AND 12 THEN
    -- get start of current year, add 9 months to get this October
    ADD_MONTHS(TRUNC(dt, 'YYYY'), 9)
  ELSE
    -- get start of current year, subtract 3 months to get previous October
    ADD_MONTHS(TRUNC(dt, 'YYYY'), -3)
  END AS calculated
FROM t
ORDER BY dt;

DT         CALCULATED
---------- ----------
2014-10-27 2014-10-01
2014-11-27 2014-10-01
2014-12-27 2014-10-01
2015-01-27 2014-10-01
2015-02-27 2014-10-01
2015-03-27 2014-10-01
2015-04-27 2014-10-01
2015-05-27 2014-10-01
2015-06-27 2014-10-01
2015-07-27 2014-10-01
2015-08-27 2014-10-01
2015-09-27 2014-10-01
2015-10-27 2015-10-01
2015-11-27 2015-10-01
2015-12-27 2015-10-01
2016-01-27 2015-10-01
2016-02-27 2015-10-01
2016-03-27 2015-10-01
2016-04-27 2015-10-01
2016-05-27 2015-10-01
2016-06-27 2015-10-01
2016-07-27 2015-10-01
2016-08-27 2015-10-01
2016-09-27 2015-10-01
2016-10-27 2016-10-01
2016-11-27 2016-10-01
2016-12-27 2016-10-01

您甚至可以简化这一过程,因此您只需截断日期一次,并进行一次ADD_MONTHS()调用,并将案例表达式放在中,因为它是您的数字加或减是唯一改变的部分:

WHERE CSMAST.CM_DATE >= ADD_MONTHS(TRUNC(sysdate, 'YYYY'),
  CASE WHEN EXTRACT(MONTH FROM sysdate) BETWEEN 10 AND 12 THEN 9 ELSE -3 END)
AND SSCTAB.RC_TYPE LIKE 'O%'

具有相同的效果。

使用两个表的模拟数据忽略显示早期日期的快速演示:

with CSMAST(cm_date, cm_call, cm_did_1) as (
  select date '1999-12-31', 1, 1 from dual
  union all select date '2014-09-30', 1, 2 from dual
  union all select date '2015-10-01', 1, 3 from dual
  union all select date '2015-12-31', 2, 4 from dual
  union all select date '2016-01-01', 2, 5 from dual
  union all select date '2016-09-30', 2, 6 from dual
  union all select date '2016-10-01', 3, 7 from dual
  union all select date '2016-12-31', 3, 8 from dual
),
SSCTAB (rc_key, rc_type) as (
  select level, 'O*' from dual connect by level < 10
)
SELECT * -- COUNT(DISTINCT CSMAST.CM_CALL)
FROM CSMAST
JOIN SSCTAB ON CSMAST.CM_DID_1 = SSCTAB.RC_KEY
WHERE CSMAST.CM_DATE >= ADD_MONTHS(TRUNC(sysdate, 'YYYY'),
  CASE WHEN EXTRACT(MONTH FROM sysdate) BETWEEN 10 AND 12 THEN 9 ELSE -3 END)
AND SSCTAB.RC_TYPE LIKE 'O%';

CM_DATE        CM_CALL   CM_DID_1     RC_KEY RC
----------- ---------- ---------- ---------- --
 2015-10-01          1          3          3 O*
 2015-12-31          2          4          4 O*
 2016-01-01          2          5          5 O*
 2016-09-30          2          6          6 O*
 2016-10-01          3          7          7 O*
 2016-12-31          3          8          8 O*

 6 rows selected