2016-04-29 48 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 
相關問題