2016-04-29 94 views
1

我正在使用Crystal Reports 13添加命令从通过Oracle 11g客户端连接的Oracle数据库中进行记录选择。我收到的错误是ORA-00933:SQL命令未正确结束,但我找不到任何与我的代码此事(不完全):SQL命令未正确结束 - Oracle子查询

/* Determine units with billing code effective dates in the previous month */ 
SELECT "UNITS"."UnitNumber", "BILL"."EFF_DT" 
FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" 
LEFT OUTER JOIN "MFIVE"."VIEW_ALL_UNITS" "UNITS" ON "BILL"."UNIT_ID" = "UNITS"."UNITID" 
WHERE "UNITS"."OwnerDepartment" LIKE '580' AND TO_CHAR("BILL"."EFF_DT", 'MMYYYY') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 

INNER JOIN 

/* Loop through previously identified units and determine last billing code change prior to preious month */ 
(
SELECT "BILL2"."UNIT_ID", MAX("BILL2"."EFF_DT") 
FROM "MFIVE"."BILL_UNIT_ACCT" "BILL2" 
WHERE TO_CHAR("BILL2"."EFF_DT", 'MMYYYY') < TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 
GROUP BY "BILL2"."UNIT_ID" 
) 

ON "BILL"."UNIT_ID" = "BILL2"."UNIT_ID" 
ORDER BY "UNITS"."UnitNumber", "BILL"."EFF_DT" DESC 

我们是租赁车辆(单位)的状态实体到其他机构。每个单位都有一个包含相关生效日期的账单代码。该应用程序将编制上个月更改帐单代码的单位的报告。

使问题复杂化的是,对于上述每个单元,报告还必须显示上个月之前的最新帐单代码和相关生效日期。一个简单的例子:

鉴于这一数据,假设现在是2016年4月(订购清晰度)...

Unit Billing Code Effective Date Excluded 
---- ------------ -------------- -------- 
1  A    04/15/2016  Present month 
1  B    03/29/2016 
1  A    03/15/2016 
1  C    03/02/2016 
1  B    01/01/2015 
2  C    03/25/2016 
2  A    03/04/2016 
2  B    07/24/2014 
2  A    01/01/2014  A later effective date prior to previous month exists 
3  D    11/28/2014  No billing code change during previous month 

报告应返回以下...

Unit Billing Code Effective Date 
---- ------------ -------------- 
1  B    03/29/2016 
1  A    03/15/2016 
1  C    03/02/2016 
1  B    01/01/2015 
2  C    03/25/2016 
2  A    03/04/2016 
2  B    07/24/2014 

任何帮助解决错误将不胜感激。

+0

'JOIN'子句不能在'WHERE'子句后面跟着 – Husqvik

回答

0

如果在Join之前的where对您真的很重要,请使用CTE。 (雇用临时表with条款并加入上是相同的。)

With c as (SELECT "UNITS"."UnitNumber", "BILL"."EFF_DT","BILL"."UNIT_ID" -- Correction: Was " BILL"."UNIT_ID" (spacetanker) 
    FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" -- Returning unit id column too, to be used in join 

LEFT OUTER JOIN "MFIVE"."VIEW_ALL_UNITS" "UNITS" ON "BILL"."UNIT_ID" = "UNITS"."UNITID" 
    WHERE "UNITS"."OwnerDepartment" LIKE '580' AND TO_CHAR("BILL"."EFF_DT", 'MMYYYY') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY')) 

    select * from c  --Filter out your required columns from c and d alias results, e.g c.UNIT_ID 
    INNER JOIN 

    --Loop through previously identified units and determine last billing code change prior to preious month */ 
    (
    SELECT "BILL2"."UNIT_ID", MAX("BILL2"."EFF_DT") 
    FROM "MFIVE"."BILL_UNIT_ACCT" "BILL2" 
    WHERE TO_CHAR("BILL2"."EFF_DT", 'MMYYYY') < TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 
    GROUP BY "BILL2"."UNIT_ID" 
    ) d 

    ON c."UNIT_ID" = d."UNIT_ID" 
    order by c."UnitNumber", c."EFF_DT" desc -- COrrection: Removed semicolon that Crystal Reports didn't like (spacetanker) 

看来这个查询有许多的范围调谐虽然。但是,有权访问数据和需求规范的人是最好的评判者。

编辑: 你是不是能够看到PRIOR数据,上月,因为你是在你原来的问题的SELECT语句,这是过滤,得到比上月(..AND TO_CHAR("BILL"."EFF_DT", 'MMYYYY') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY'))

的唯一日期使用BILL.EFF_DT如果你想要的数据是你想要的,我想你必须使用BILL2部分(d部分在我的子查询中),给别名赋予Max(EFF_DT),并在你的select子句中使用这个别名。

+0

@ IaB,谢谢。你的建议似乎包含了逻辑,但是当我尝试执行它时,CR返回了可怕的SQL命令没有正确结束的错误。现在详细看看它。 – spacetanker

+0

@spacetanker,我错过了bill.unit_id in c。编辑。 –

+0

@IaB。不幸的是仍然收到相同的错误信息。 – spacetanker

1

您在INNER JOIN条款之前有WHERE子句。这是无效的语法 - 如果换成他们应该工作:

SELECT "UNITS"."UnitNumber", 
     "BILL"."EFF_DT" 
FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" 
     LEFT OUTER JOIN 
     "MFIVE"."VIEW_ALL_UNITS" "UNITS" 
     ON "BILL"."UNIT_ID" = "UNITS"."UNITID" 

INNER JOIN 

/* Loop through previously identified units and determine last billing code change prior to preious month */ 
    (
    SELECT "UNIT_ID", 
      MAX("EFF_DT") 
    FROM "MFIVE"."BILL_UNIT_ACCT" 
    WHERE TO_CHAR("EFF_DT", 'MMYYYY') < TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 
    GROUP BY "UNIT_ID" 
    ) "BILL2" 

    ON "BILL"."UNIT_ID" = "BILL2"."UNIT_ID" 
WHERE "UNITS"."OwnerDepartment" LIKE '580' 
AND TO_CHAR("BILL"."EFF_DT", 'MMYYYY') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'MMYYYY') 
ORDER BY "UNITS"."UnitNumber", "BILL"."EFF_DT" DESC 

此外,您还需要移动"BILL2"别名()括号外,你不需要括号内的别名,但你做的外面。

你确定你需要双引号""?双引号在列名中强制区分大小写 - 默认行为是Oracle将所有表名和列名转换为大写字母,以便从用户中抽象区分大小写 - 因为您同时使用双引号和大写名称,报价似乎是多余的。

+0

@MTD谢谢。我认为语法问题正在困扰着我。 毫无疑问,我如何构建查询,但结果记录仅显示上个月内的更改。将WHERE子句移到最后限制输出以排除上个月之前的最新生效日期。 – spacetanker

1

SOLUTION :

SELECT DISTINCT "BILL2".* 
FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" 
LEFT JOIN 

    /* Returns all rows for each unit with effective date >= maximum prior effective date and effective date < current month */ 
    (
    SELECT "UNITS"."UnitNumber" AS "UNITNO", 
    UPPER("UNITS"."SpecNoDescription") AS "TS_DESCR", 
    "UNITS"."UsingDepartment" AS "USING_DEPT", 
    "UNITS"."OwnerDepartment" AS "OWNING_DEPT", 
    "BILL"."BILLING_CODE", 
    "BILL"."EFF_DT", 
    "BILL"."UNIT_ID" 
    FROM "MFIVE"."BILL_UNIT_ACCT" "BILL" 
    LEFT OUTER JOIN "MFIVE"."VIEW_ALL_UNITS" "UNITS" ON "BILL"."UNIT_ID" = "UNITS"."UNITID" 
    WHERE TO_NUMBER(TO_CHAR(TRUNC("BILL"."EFF_DT"), 'YYYYMM'), '999999') < TO_NUMBER(TO_CHAR(TRUNC(ADD_MONTHS(SYSDATE, 0)), 'YYYYMM'), '999999') AND 
"UNITS"."OwnerDepartment" = '580' AND 
"BILL"."EFF_DT" >= 

    /* Returns maximum effective date prior to previous month for each unit */ 
    (
    SELECT MAX("BILL3"."EFF_DT") 
    FROM "MFIVE"."BILL_UNIT_ACCT" "BILL3" 
    WHERE "BILL3"."UNIT_ID" = "BILL"."UNIT_ID" AND 
     TO_NUMBER(TO_CHAR(TRUNC("BILL3"."EFF_DT"), 'YYYYMM'), '999999') < TO_NUMBER(TO_CHAR(TRUNC(ADD_MONTHS(SYSDATE, -1)), 'YYYYMM'), '999999') 
    GROUP BY "BILL3"."UNIT_ID" 
    ) 

) BILL2 

ON "BILL"."UNIT_ID" = "BILL2"."UNIT_ID" 
WHERE TO_CHAR("BILL"."EFF_DT", 'YYYYMM') = TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE), -1), 'YYYYMM') 
ORDER BY "BILL2"."UNITNO", "BILL2"."EFF_DT" DESC 
相关问题