2016-08-16 22 views
0

SQL新手,瞭解基本查詢,試圖寫出比我的知識稍高一些的東西,並且如果有人能夠提供它,需要一些幫助。我已經嘗試過使用模板代碼並根據我的需要進行剪裁,但沒有成功。SQL,發票聲明,當前和過去的會費

我正在處理1個表格,並嘗試獲取查詢以顯示客戶當前的0-30天餘額以及30-60,60-90,90-120,120天以上的任何過期日期。

table: c_inv_h 
columns: comp_code, cust_code, inv_num, inv_date, inv_tp, inv_amt, inv_tax1, inv_tax2 

例如數據

comp_code, cust_code, inv_num, inv_date, inv_tp, inv_amt, inv_tax1, inv_tax2 
M1, 100068, 1, 2016-08-11, RCPT, 103.48, 4.5, 8.98 
M1, 100068, 2, 2016-07-11, RCPT, 103.48, 4.5, 8.98 
M1, 100068, 3, 2016-06-11, RCPT, 103.48, 4.5, 8.98 
M1, 200027, 4, 2016-05-11, RCPT, 103.48, 4.5, 8.98 
M1, 200027, 5, 2016-04-11, RCPT, 103.48, 4.5, 8.98 

我想讓查詢顯示:

comp_code, cust_code, CurrentBalance, 30-60, 60-90, 90-120, 120+ 
M1, 100068, 116.96, 233.92, 0, 0, 0 
M1, 200027, 0, 233.92, 0, 0, 0 
M1, 200027, 0, 0, 0, 0, 233.92 

我到目前爲止已經試過

SELECT comp_code, cust_code, inv_num, inv_date, sum(inv_amt) + sum(inv_tax1) 
+ sum(inv_tax2) as InvoiceTotal, 
DATEDIFF(day, inv_date, sysdate as Numberofdays, 'CurrentBalance' = 
CASE WHEN DATEDIFF(day,inv_date, sysdate < 30 then InvoiceTotal END, 
'30_days' = CASE WHEN DATEDIFF(day, inv_date, sysdate between 30 AND 60 
Then InvoiceTotal WHEN DATEDIFF(day, inv_date, sysdate > 90 Then 
InvoiceTotal END 
FROM c_inv_h 
WHERE comp_code='M1' 
GROUP BY comp_code, cust_code 

這可能是遙遠從我試圖實現,但我試着克通過它。

非常感謝提前!

+0

Alan歡迎來到stackoverflow!你有一個好的開始你的問題,但也應該包括你想要的結果是基於你的示例數據,並告訴我們你已經嘗試過的東西。不要擔心,如果它是失敗或不起作用,它只是幫助我們知道我們正在幫助你不爲你做,並可以產生一些額外的洞察你想要的邏輯。 – Matt

+0

感謝馬特。我編輯了我的帖子。 –

+0

您可以使用條件聚合來創建像這樣的數據透視表。但取決於哪個數據庫/ rdbms(sql-server,oracle,mysql)可能有一些其他選項可用於您使用的是什麼系統?也可以在你想要查詢的內容中放置一行daa,它可以幫助人們更好地形象化 – Matt

回答

0

你在正確的軌道上想着有條件的聚合。您只需刪除不參與聚合的列並清理語法錯誤。

SELECT 
    comp_code 
    ,cust_code 
    ,SUM(CASE 
      WHEN DATEDIFF(CURDATE(),inv_date) < 30 
      THEN COALESCE(inv_amt,0.00) + COALESCE(inv_tax1,0.00) + COALESCE(inv_tax2,0.00) 
      ELSE 0 
     END 
    ) AS CurrentBalance 
    ,SUM(CASE 
      WHEN DATEDIFF(CURDATE(),inv_date) >= 30 AND DATEDIFF(CURDATE(),inv_date) < 60 
      THEN COALESCE(inv_amt,0.00) + COALESCE(inv_tax1,0.00) + COALESCE(inv_tax2,0.00) 
      ELSE 0 
     END 
    ) AS "30-60" 
    ,SUM(CASE 
      WHEN DATEDIFF(CURDATE(),inv_date) >= 60 AND DATEDIFF(CURDATE(),inv_date) < 90 
      THEN COALESCE(inv_amt,0.00) + COALESCE(inv_tax1,0.00) + COALESCE(inv_tax2,0.00) 
      ELSE 0 
     END 
    ) AS "60-90" 
    ,SUM(CASE 
      WHEN DATEDIFF(CURDATE(),inv_date) >= 90 AND DATEDIFF(CURDATE(),inv_date) < 120 
      THEN COALESCE(inv_amt,0.00) + COALESCE(inv_tax1,0.00) + COALESCE(inv_tax2,0.00) 
      ELSE 0 
     END 
    ) AS "90-120" 
    ,SUM(CASE 
      WHEN DATEDIFF(CURDATE(),inv_date) >= 120 
      THEN COALESCE(inv_amt,0.00) + COALESCE(inv_tax1,0.00) + COALESCE(inv_tax2,0.00) 
      ELSE 0 
     END 
    ) AS "120+" 
FROM 
    c_inv_h 
WHERE 
    comp_code='M1' 
GROUP BY 
    comp_code, cust_code 
; 

我使用COALESCE以確保有一個值,因爲添加列時,如果添加1個+ NULL + 1個的結果將是NULL。當使用聚合函數時,例如SUM()它會忽略NULL值。因爲您正在使用兩者取決於您的數據集,您可能需要將COALESCE幫助的0賦給NULL。

接下來我不使用BETWEEN,因爲BETWEEN包含了比較的兩個方面,所以如果你說一列之間在30到60之間,另一列在60到90之間,並且數額是60天過期,它將是在兩列中。

最後您的示例輸出對於您提供的示例數據不正確,因爲日期相距5,36,66,97和127天,但我非常肯定我明白你想要什麼。

希望有所幫助。

+0

謝謝馬特。請隨身攜帶,慢慢學習並理解你寫的內容。我試過測試這個腳本,並且我收到了錯誤,例如無效的表名,所以我從@c_inv_h中取出了@,然後我發現DATEDIFF是一個無效標識符的錯誤。然後我試着用STARTDATE代替DATEDIFF,這也是一個無效的標識符。 'java.sql。SQLException:ORA-00903:invalid table name', 'java.sql.SQLException:ORA-00904:「DATEDIFF」:無效標識符' –

+0

抱歉,我在那裏留下了@符號我使用了sql-server表變量來測試和建立查詢。我也沒有改變一些語法的東西到MySQL版本。我基於查看查詢來快速構建查詢,我想我應該在mysql中完成它以開始。 SQLFiddle是一個網站,可以讓你測試不同數據庫中的一些代碼,這裏是一個測試鏈接,顯示更新後的答案正在工作。 http://sqlfiddle.com/#!9/40271/4 – Matt

+0

感謝Matt,我能夠讓你的腳本在MySQL中工作,然後我在公司服務器數據庫上嘗試了它,並且沒有avai。我是個笨蛋,數據庫在Oracle上運行,而不是在mysql上運行,所以我試圖將它調整爲Oracles函數名稱。 ' SELECT COMP_CODE,CUST_CODE,CASE WHEN TO_DATE(SYSDATE) - TO_DATE(inv_date)<30 THEN COALESCE(inv_amt,0.00)ELSE 0 AS CurrentBalance FROM c_inv_h WHERE COMP_CODE =' M1' GROUP BY COMP_CODE,CUST_CODE」 ' 你看到我要在這裏錯了嗎? –