2017-08-14 37 views
1

我想在一列上使用case語句,並在條件滿足時計算另一列的聚合。在一列上使用CASE語句並計算另一列的聚合

,我查詢看上去像這樣的樣本數據表(用於酒店爲例):

| date | customer_name | customer_id | expense_type | billed_amount | 
| 08-02 | John Doe |  1  | personal |  120.00 | 
| 08-03 | John Doe |  1  | personal |  80.00 | 
| 08-04 | John Doe |  1  | corporate |  205.00 | 
| 08-02 | Adam Smith |  2  | corporate |  400.00 | 
| 08-03 | Adam Smith |  2  | personal |  300.00 | 
| 08-06 | Adam Smith |  2  | corporate |  150.00 | 

下面是SQL查詢我寫道:

Select 
    customer_name 
    , customer_id 
    , case when expense_type = 'personal' then sum(billed_amount) else 0 end as personal_bill 
    , case when expense_type = 'corporate' then sum(billed_amount) else 0 end as corporate_bill 
From payments 
Where date > '08-01' 
Group by 1, 2 

錯誤消息我得到是:

Column "expense_type" must appear in the GROUP BY clause or be used in an aggregate function 

當我嘗試組3列(以及1和2),我收到此錯誤消息:

Aggregates not allowed in GROUP BY clause 

最後,下面示出所希望的結果表:

| customer name | customer_id | personal_bill | corporate_bill | 
| John Doe |  1  |  200.00 |  205.00  | 
| Adam Smith |  2  |  300.00 |  550.00  | 

一種解決方案,我能想到是創建限制在哪裏部分中的「expense_type」兩個不同的子查詢(即where expense_type ='personal'),然後在主查詢中查詢它們,但這是很多類似的代碼,只有一行的區別。你能幫我以有效的方式寫這個查詢嗎?謝謝!

回答

0

使用filter

select 
    customer_name, 
    customer_id, 
    sum(billed_amount) filter (where expense_type = 'personal') as personal_bill, 
    sum(billed_amount) filter (where expense_type = 'corporate') as corporate_bill 
from payments 
where date > '08-01' 
group by 1, 2 

customer_name | customer_id | personal_bill | corporate_bill 
---------------+-------------+---------------+---------------- 
Adam Smith |   2 |  300.00 |   550.00 
John Doe  |   1 |  200.00 |   205.00 
(2 rows)  
+0

didn'瞭解「過濾器」語法;謝謝! – Joe

0

總和整個CASE表達:

select 
    customer_name, 
    customer_id, 
    sum(case when customer_type = 'personal' 
      then billed_amount else 0 end) as personal_bill 
    sum(case when customer_type = 'corporate' 
      then billed_amount else 0 end) as corporate_bill 
from payments 
where date > '08-01' 
group by 1, 2 
+0

非常感謝你的答案 - 這可能是最接近於我一直在尋找,但選擇與「過濾器」的其他答案,因爲這是一個新的概念,我通過這個瞭解到問題 – Joe

+0

@Joe我也不知道這個。值得注意的是,接受的答案不會在任何其他數據庫上運行。 –

0

試試這個: -

Select MIN(customer_name) AS customer_name, customer_id, 
     SUM(case when expense_type = 'personal' then billed_amount::double precision else 0 end) as personal_bill, 
     SUM(case when expense_type = 'corporate' then billed_amount::double precision else 0 end) as corporate_bill 
From payments 
Where date > '08-01' 
Group by customer_id 
ORDER BY customer_id; 
+0

非常感謝您的回答 - 這與我一直在尋找的內容非常接近,但選擇了其他答案與「過濾器」,因爲這是一個新概念,我通過這個問題了解到 – Joe

+0

好吧當然... @Joe – Amit