2015-11-04 39 views
1

我在過去的兩週中一直受到這個問題的折磨,無法再花費更多時間。如果你有一分鐘​​的話,我很樂意聽到這個社區的任何想法。我是自學成才的,所以我必須按照內部條件解釋這一點。謝謝您的考慮。Oracle SQL:使用存儲過程獲取由逗號分隔的ID字段連接的數據

我的目標是獲取所有非零餘額的發票。這對於定期發票來說足夠簡單。問題出現在付款提醒中,因爲它們的餘額只是滯納金,所以爲了取得總餘額,我必須通過連接表COLLECTIVEINVOICENO中的單個字段鏈接回原始發票。表INVOICE

例子:

invoiceid  | invoiceno  | invoicetypename  | amount 
--------------|---------------|---------------------|-------------------- 
10008   | 123000  | Payment Reminder | 5 
10005   | 113000  | Payment Reminder | 5 
10001   | 110000  | Invoice    | 35 

COLLECTIVEINVOICENO其中1000110005過期的例子:

invoiceid  | followed_up_in (CHAR) 
--------------|---------------------------------------------------------- 
10005   | 113000, 123000 
10001   | 113000 

我已經找到了一個非常壞的解決方案,其工作方式獲取的總賬一次只有一個客戶,但它對資源的要求太高,我無法在整個桌子上使用它INVOICE

select (
    select sum(i.amount) as sum 
    from INVOICE i0 
    join COLLECTIVEINVOICENO cin0 on cin0.invoiceid = i0.invoiceid 
    where instr(cin0.followed_up_in, i.invoiceno) > 0 
) as original_sum 
from INVOICE i 

這全表掃描,重複5次在我的主select以各種餘額爲不同的列進行排序,並取出來自原始發票等資料,除了他們的平衡,比如它們的位置等

我最初的意圖是將子查詢左鍵加入INVOICE i作爲視圖,但Oracle在instr(cin0.collectiveinvoiceno, i.invoice)(ORA-00904:「I」,「INVOICENO」:無效標識符)中不識別i.invoice

我現在正在尋找目前正在做的遊標等,但我真的想知道是否有任何SQL,非PL的方式呢?

謝謝。

編輯:關於將逗號分隔的數據分成行,即。改變數據模型以促進關係:這肯定會幫助我確信,但是數據模型與第三方軟件打包在一起,所以我對此無能爲力。 (如果他們確實在某些時候改變了它,我不會感到驚訝)

編輯2:嘗試將逗號分隔數據拆分爲行,使用regexp_substr()levelconnect by並將此視圖加入主表。我沒有解決問題,因爲當regexp_substr()在其他表加入時資源明顯昂貴,並且即使在半小時後查詢也無法提供。谷歌顯示,這是正則表達式的常見問題,建議您嘗試使用存儲過程。

我已經改變了標題以反映這一點,我將不勝感激關於如何使用存儲過程來解決這個問題的任何輸入。不管怎樣,謝謝!

+0

[字符串分割爲多行中的Oracle]的可能的複製(http://stackoverflow.com/questions/14328621/splitting-string-into-multiple-rows-in-oracle) – gmiley

+5

存儲逗號分隔關係列中的值是通向心痛的路徑。你確定你不想修復底層的數據模型問題,這樣你就可以讓數據庫爲你工作,而不是讓它與你作鬥爭? –

+0

我不確定您是否錯誤地鍵入了您的示例,或者我只是沒有遵循數據模型。根據你在這裏給出的樣本數據,你是描述,很難判斷10001和10005是否獨立。你期望看到什麼最終的平衡?只有一行 - INVOICE 10001 - 餘額爲45? – KevinKirkpatrick

回答

1

這可能有幫助。它將分隔逗號分隔followed_up_in,並在加入主表之前使用xmltable將產生的列表值平鋪成發票號碼行。

 select i0.invoiceid, sum(i0.amount) 
     from INVOICE i0 
     left outer join 
     (select invoice_id, trim(COLUMN_VALUE) invoiceno 
      FROM COLLECTIVEINVOICENO, 
       xmltable(('"' || REPLACE(followed_up_in, ',', '","') || '"')) 
    ) cin0 
     on cin0.invoiceno = i0.invoiceno 
     and i0.invoiceid = cin0.invoiceid 
     group by i0.invoiceid 
+0

謝謝Thomas,看起來很棒。我明天會嘗試。 – IngridSkard

+0

我遵循了你的建議托馬斯和甲骨文運行它,但它運行「永遠」。當單元測試時,我發現regexp_substr()似乎會導致掛斷。當我從dual運行regexp_substr()時,它的運行沒有延遲。我不知道開發者是否可以對他們的觀點(我正在從觀點來看)使用'level'這個限制,或者是這樣。不管怎麼說,還是要謝謝你。 – IngridSkard

+0

呃,事實證明'regexp_substr()'只能在主表上沒有其他東西被加入時傳遞,即在視圖中和主'select'下! – IngridSkard