我有一個派生表中包含列:找出第一個記錄是一定值以上
- 電子郵件(主標識符)
- transaction_time
- 量
如何看待對於PostgreSQL中的第一個事務,基於amount > 500
的客戶(通過電子郵件標識)?
注意:這用於用於過濾主表的子查詢。
我有一個派生表中包含列:找出第一個記錄是一定值以上
如何看待對於PostgreSQL中的第一個事務,基於amount > 500
的客戶(通過電子郵件標識)?
注意:這用於用於過濾主表的子查詢。
這也許應該這樣做:
SELECT DISTINCT ON (email) *
FROM t
WHERE amount > 500
ORDER BY email, transaction_time
它將返回第一筆交易(相對於transaction_time
)爲每封電子郵件。
馬特,請看看DISTINCT ON。 –
下面的解決方案將更便攜,DISTINCT ON
這是Postgres特定的。使用row_number()
枚舉行,並得到所有不同的客戶(通過電子郵件標識)有他們的第一筆交易金額大於500
編輯:我已經包括三種方式來達到同樣的效果。選擇你喜歡的任何一個。
第一種方法 - 使用row_number()
select
distinct email
from (
select
email,
amount,
row_number() OVER (PARTITION BY email ORDER BY transaction_time) AS rn
from <derived_table_here>
) t
where
rn = 1
and amount > 500
第二條本辦法 - 使用DISTINCT ON
select
email
from (
select distinct on (email)
email,
amount
from <derived_table_here>
order by email, transaction_time
) t
where amount > 500
第三種方法 - 使用NOT EXISTS
select
email
from <derived_table_here> t1
where
amount > 500
and not exists(
select 1
from <derived_table_here> t2
where
t1.email = t2.email
and t1.transaction_time > t2.transaction_time
)
我發現第三種方法最便攜,因爲MySQL實例不支持窗口函數AFAIK。這僅僅是在將來在數據庫之間切換的情況下 - 對你來說更少的工作。
測試下面樣品:
email | transaction_time | amount
-----------------+----------------------------+--------
[email protected] | 2016-09-26 19:01:15.297251 | 400 -- 1st, amount < 500
[email protected] | 2016-09-26 19:01:19.160095 | 500
[email protected] | 2016-09-26 19:01:21.526307 | 550
[email protected] | 2016-09-26 19:01:28.659847 | 600 -- 1st, amount > 500
[email protected] | 2016-09-26 19:01:30.292691 | 200
[email protected] | 2016-09-26 19:01:31.748649 | 300
[email protected] | 2016-09-26 19:01:38.59275 | 200 -- 1st, amount < 500
[email protected] | 2016-09-26 19:01:40.833897 | 100
[email protected] | 2016-09-26 19:01:51.593279 | 501 -- 1st, amount > 500
根據我的理解,適用where條款可能會取消第一筆交易的資格,而我們不能在第一筆交易中取消第一筆交易的資格,不管這筆交易在開始時是多少,而是將其標記爲第一筆交易。 –
@Matt其實我已經測試過了,你錯了。 –
是的,我錯過了你最初在做什麼,並以不同的方式解釋它。但在1個查詢中仍然有更好的方法 – Matt
另一種選擇:
select * from t t1
where amount > 500
and not exists
(select 1 from t t2 where t1.email=t2.email and t1.transaction_time>t2.transaction_time)
LEFT SELF連接方法
SELECT t1.*
FROM
ExmapleTable t1
LEFT JOIN ExmapleTable t2
ON t1.Email = t2.Email
AND t2.transaction_time < t1.transaction_time
WHERE
t1.Amount >= 500
AND t2.Email IS NULL
;
您可以添加示例數據和預期結果。 –