TL;博士在最後的代碼塊應該給你想你想,有一些細微的變化,使其在postgre工作
使用子查詢是一個比較中間的話題,所以不要泄氣如果你沒有得到它。我會在幾個步驟中通過它。
(1)組成的一些試驗數據和連接表
(2)選擇最近期Positiv請求
(3)是負面的量的SELECT SUM
(4)選擇的positiv比到是負面的計數
測試數據和參考
對於這個答案,我將使用下表作爲測試數據:
#user_account
+ ---------- + ------------- + ------------ +
| account_id | creation_date | account_type |
+ ---------- + ------------- + ------------ +
| 1 | 2016-02-14 | B |
| 2 | 2016-02-14 | A |
| 3 | 2016-04-06 | B |
| 4 | 2016-04-29 | B |
| 5 | 2016-09-03 | A |
+ ---------- + ------------- + ------------ +
#request
+ ---------- + ------------- + ---------- + ------- + ------------ +
| request_id | creation_date | account_id | amount | request_type |
+ ---------- + ------------- + ---------- + ------- + ------------ +
| 1 | 2016-03-08 | 1 | 4308.02 | positiv |
| 2 | 2016-04-08 | 1 | 1718.56 | negativ |
| 3 | 2016-03-11 | 2 | 911.50 | positiv |
| 4 | 2016-03-12 | 2 | 38.42 | negativ |
| 5 | 2016-03-12 | 2 | 110.12 | positiv |
| 6 | 2016-05-08 | 3 | 1843.19 | positiv |
| 7 | 2016-09-12 | 4 | 7234.11 | negativ |
| 8 | 2016-10-12 | 4 | 515.51 | negativ |
| 9 | 2016-10-12 | 5 | 0.01 | positiv |
| 10 | 2016-10-18 | 5 | 13.02 | positiv |
+ ---------- + ------------- + ---------- + ------- + ------------ +
我將使用table aliasing,我已經改名申請表的類型字段request_type。哦,還有一兩件事:這是寫在SQL Server中,但它應該postgre工作,只有輕微的修改:)
開始簡單的,讓我們的表連接在一起,並在ACCOUNT_TYPE
select *
from #user_account u
inner join #request r on r.account_id = u.account_id
where u.account_type = 'A'
濾除給出了下面的表,我將作爲參考
+ ---------- + ------------- + ------------ + ---------- + ------------- + ------ + ------------ +
| account_id | creation_date | account_type | request_id | creation_date | amount | request_type |
+ ---------- + ------------- + ------------ + ---------- + ------------- + ------ + ------------ +
| 2 | 2016-02-14 | A | 3 | 2016-03-11 | 911.5 | positiv |
| 2 | 2016-02-14 | A | 4 | 2016-03-12 | 38.42 | negativ |
| 2 | 2016-02-14 | A | 5 | 2016-03-12 | 110.12 | positiv |
| 5 | 2016-09-03 | A | 9 | 2016-10-12 | 0.01 | positiv |
| 5 | 2016-09-03 | A | 10 | 2016-10-18 | 13.02 | positiv |
+ ---------- + ------------- + ------------ + ---------- + ------------- + ------ + ------------ +
選擇申請
使用
爲了理解相關的子查詢,我們假設我有上面的表格和一個變量@account_id = 2
。通過查看參考表,我們可以看到,對於帳戶2,我們希望選擇reference_id 5,因爲它是最近的正式請求。下面的查詢讓我們只是
select top 1 request_id
from #request
where account_id = @account_id
and request_type = 'positiv'
order by creation_date desc
要在我們的查詢使用這個想法,我們需要用u.account_id
更換@account_id
,像這樣
select u.account_id
, r.request_id
, r.creation_date
, r.amount
from #user_account u
inner join #request r on r.account_id = u.account_id
where u.account_type = 'A'
and r.request_id = (
select top 1 request_id
from #request
where account_id = u.account_id -- correlate to the reference table
and request_type = 'positiv'
order by creation_date desc
)
這讓我們把它變成一個相關子查詢正是我們想要
+ ---------- + ---------- + ------------- + ------ +
| account_id | request_id | creation_date | amount |
+ ---------- + ---------- + ------------- + ------ +
| 2 | 5 | 2016-03-12 | 110.12 |
| 5 | 10 | 2016-10-18 | 13.02 |
+ ---------- + ---------- + ------------- + ------ +
選擇是負面的總和金額
我們將在後面兩部分中使用相關子查詢的相同概念,但在這裏我們將它們放在語句的選擇部分,因爲我們不再需要過濾掉任何結果。該查詢
select u.account_id
, r.request_id
, r.creation_date
, r.amount
, (select isnull(SUM(amount),0) -- replaces a null value with 0
from #request
where account_id = u.account_id
and request_type = 'negativ') as SumOfFailed
from ... -- same as above
給我們
+ ---------- + ---------- + ------------- + ------ + ----------- +
| account_id | request_id | creation_date | amount | SumOfFailed |
+ ---------- + ---------- + ------------- + ------ + ----------- +
| 2 | 5 | 2016-03-12 | 110.12 | 38.42 |
| 5 | 10 | 2016-10-18 | 13.02 | 0 |
+ ---------- + ---------- + ------------- + ------ + ----------- +
選擇比
我們基本上做同樣的事情在這裏,但它可能很容易迷失在鑄造和除零檢查。所以希望我把它拆分成夠線,它清楚地
select u.account_id
, r.request_id
, r.creation_date
, r.amount
, (...) as SumOfFailed -- same as above
, cast((-- convert integer to float
select COUNT(*)
from #request
where account_id = u.account_id
and request_type = 'positiv'
) as float)
/nullif(-- if divisor is zero, return null
CAST((
select COUNT(*)
from #request
where account_id = u.account_id
and request_type = 'negativ'
) as float), 0) as Ratio
from ... -- same as above
這讓我們
+ ---------- + ---------- + ------------- + ------ + ----------- + ----- +
| account_id | request_id | creation_date | amount | SumOfFailed | Ratio |
+ ---------- + ---------- + ------------- + ------ + ----------- + ----- +
| 2 | 5 | 2016-03-12 | 110.12 | 38.42 | 2 |
| 5 | 10 | 2016-10-18 | 13.02 | 0 | Null |
+ ---------- + ---------- + ------------- + ------ + ----------- + ----- +
代碼塊
因此,所有一起,你將SQL語句是這樣的,有一些小的差異,使其在Postgre中工作。
select u.account_id
, request_id
, r.creation_date
, r.amount
, (select isnull(SUM(amount),0) -- replaces a null value with 0
from #request
where account_id = u.account_id
and request_type = 'negativ') as SumOfFailed
, cast((
select COUNT(*)
from #request
where account_id = u.account_id
and request_type = 'positiv'
) as float)
/nullif(
CAST((
select COUNT(*)
from #request
where account_id = u.account_id
and request_type = 'negativ'
) as float),0) as Ratio
from #user_account u
inner join #request r on r.account_id = u.account_id
where u.account_type = 'A'
and r.request_id = (
select top 1 request_id
from #request r_sq
where r_sq.account_id = u.account_id
and r_sq.request_type = 'positiv'
order by creation_date desc
)
希望這有助於!
可能不會解決所有問題,請注意,您所做的連接意味着您獲得了所有請求(添加了有關相應用戶的列和數據),而不僅僅是最後的請求。我會首先找到每個用戶最後一次請求的日期 - 「SELECT account_id,MAX(timestamp)FROM request GROUP BY account_id' –