2015-09-18 35 views
0

在Crystal Reports中,我使用下面的查詢(針對Oracle數據庫)來生成一個報告,其中單場數據:運行Oracle SQL查詢過幾次約會

SELECT SUM(e1.ENT_LOCAL_AMOUNT+e1.ENT_DISCRETIONARY_AMOUNT) AS "Entitlement" 
FROM CLAIM_PERIODS cp1 
JOIN ENTITLEMENTS e1 
    ON cp1.CPE_REFNO=e1.ENT_CPE_REFNO 
WHERE e1.ENT_REFNO=(SELECT MAX(to_number(e2.ENT_REFNO)) 
    FROM ENTITLEMENTS e2 
    WHERE e1.ENT_CPE_REFNO=e2.ENT_CPE_REFNO 
    AND (e2.ENT_START_DATE <= {?HB_As_At_Date} 
    AND e2.ENT_END_DATE > {?HB_As_At_Date}) 
    AND e2.ENT_CREATED_DATE<={?HB_As_At_Date}) 
    AND cp1.CPE_CPA_CPY_CODE='HB' 

這工作正常,並返回基於{?HB_As_At_Date}提供的單個整數值({?}語法是Crystal將參數值嵌入到SQL中的方式)。上述查詢的內容並不是我的問題 - 我想要做的是在多個不同的日期重複運行它,並將輸出傳遞給Crystal以供報表使用。

所以說,我要爲每星期一在今年9查詢運行,與2015年7月9日參數爲14/09/2015我目前運行Crystal報表一次,然後再等

我寧願將我的SELECT語句與根據需要列出的查詢結合使用 - 每次需要每個日期運行一次。隨着輸出是這樣的:

Date  Entitlement 
07/09/2015 450,000.00 
14/09/2015 460,123.00 
21/09/2015 465,456.00 
28/09/2015 468,789.00 

有人能指出我在正確的方向,我應該在這裏讀哪些關鍵字?我想可以直接生成一組日期並使用它們作爲子查詢來運行我的SQL,但我不確定從哪裏開始。

+0

我能想到的唯一方法是創建存儲過程(SP)。你必須決定你可以使用的最大日期數,比如說5,然後把它們作爲參數傳遞給SP。在SP內部,您逐個檢查參數以查看它們是否具有值或NULL。爲每個具有值的參數運行一次查詢並返回結果。 –

+0

非常感謝您的回覆。我無法在數據庫上創建存儲過程,但會查看是否可以安排。我會認爲有一個更好的方法來做 - 也會繼續調查。 – Sami

+0

是的,我明白你的意思。我也儘可能地避免存儲過程。如果你真的想在查詢中做到這一點,有一個醜陋的方式來做到這一點。您必須重複查詢每個日期參數,然後使用'UNION'組合這些子查詢。你想讓我發佈這個答案嗎? –

回答

0

我能想到的不使用存儲過程的唯一方法是通過重複(即複製/粘貼)每個日期參數的查詢,然後將它們作爲使用UNION的子查詢進行組合。這樣的事情:

SELECT SUM(e1.ENT_LOCAL_AMOUNT+e1.ENT_DISCRETIONARY_AMOUNT) AS "Entitlement" 
FROM CLAIM_PERIODS cp1 
JOIN ENTITLEMENTS e1 
    ON cp1.CPE_REFNO=e1.ENT_CPE_REFNO 
WHERE e1.ENT_REFNO=(SELECT MAX(to_number(e2.ENT_REFNO)) 
    FROM ENTITLEMENTS e2 
    WHERE e1.ENT_CPE_REFNO=e2.ENT_CPE_REFNO 
    AND (e2.ENT_START_DATE <= {?HB_As_At_Date_1} 
    AND e2.ENT_END_DATE > {?HB_As_At_Date_1}) 
    AND e2.ENT_CREATED_DATE<={?HB_As_At_Date_1}) 
    AND cp1.CPE_CPA_CPY_CODE='HB' 

UNION 

SELECT SUM(e1.ENT_LOCAL_AMOUNT+e1.ENT_DISCRETIONARY_AMOUNT) AS "Entitlement" 
FROM CLAIM_PERIODS cp1 
JOIN ENTITLEMENTS e1 
    ON cp1.CPE_REFNO=e1.ENT_CPE_REFNO 
WHERE e1.ENT_REFNO=(SELECT MAX(to_number(e2.ENT_REFNO)) 
    FROM ENTITLEMENTS e2 
    WHERE e1.ENT_CPE_REFNO=e2.ENT_CPE_REFNO 
    AND (e2.ENT_START_DATE <= {?HB_As_At_Date_2} 
    AND e2.ENT_END_DATE > {?HB_As_At_Date_2}) 
    AND e2.ENT_CREATED_DATE<={?HB_As_At_Date_2}) 
    AND cp1.CPE_CPA_CPY_CODE='HB' 

至於你對寫劇本的評論,我不知道你是如何運行你的報告。但是如果你有一個運行它的應用/網站,那麼你可以用應用/網站的語言生成SQL,並在運行之前將它分配給報告對象。或者甚至更好,您可以生成SQL,運行它並將結果分配給報表對象。我一直這樣做,因爲我更喜歡我的代碼來運行查詢,而不是報告本身,因爲我遵循我的應用程序中的分層設計模式。該報告將位於無法直接與數據庫通信的表示層,而是通過生成/運行查詢調用業務/數據層,並將結果返回給業務/表示層。

+0

非常感謝Racil。這是有道理的,也許是我現在所能期望的最好的 - 除非我在調查中發現其他任何東西。我會研究一些生成SQL的方法 - 應該很簡單。道歉 - 我不能公開提出你的答案,因爲我是新手,但在這裏標記爲最有幫助。 – Sami

+0

不用擔心,我很樂意提供幫助。 –

0

編輯參數把輸入的多個值,並更改查詢作爲

使用開始或結束,但不能同時

SELECT SUM(e1.ENT_LOCAL_AMOUNT+e1.ENT_DISCRETIONARY_AMOUNT) AS "Entitlement" 
FROM CLAIM_PERIODS cp1 
JOIN ENTITLEMENTS e1 
    ON cp1.CPE_REFNO=e1.ENT_CPE_REFNO 
WHERE e1.ENT_REFNO=(SELECT MAX(to_number(e2.ENT_REFNO)) 
    FROM ENTITLEMENTS e2 
    WHERE e1.ENT_CPE_REFNO=e2.ENT_CPE_REFNO 
    AND e2.ENT_END_DATE in ({?HB_As_At_Date}) 
    AND e2.ENT_CREATED_DATE in ({?HB_As_At_Date}) 
    AND cp1.CPE_CPA_CPY_CODE='HB' 
+0

謝謝。這仍然會涉及手動選擇所需的每個日期 - 雖然這是一次又一次重新運行報告時做同樣事情的改進。會試試看。我需要更改一下查詢,因爲只要ENT_CREATED_DATE小於或等於所提供的參數,ENT_CREATED_DATE就可以是任何值。所以不一定完全等於所提供的日期。同樣ENT_START_DATE和ENT_END_DATE。但我明白你對多種價值的含義 - 謝謝 - 即使我不希望達到目前的情況,也能改善目前的狀況。 :) – Sami