PostgreSQL - 计算售出机构的数量
PostgreSQL - Calculating number of institutions that sold counts
我们有一个叫 'holdings' 的 table。
包含各季度金融机构持股数量信息。
其中有以下列:
institution_id
symbol
shares
quarter
1
AAPL
0
2020_Q4
2
TSLA
200000
2020_Q4
1
AAPL
100000
2020_Q3
我们要计算编号。在特定季度出售了特定公司(用符号表示)的持股的机构的数量。
我们目前有这样的查询,但我认为它可以改进。
select count(*) as "soldCount",sum(q3.shares) as "soldShares" from
(select * from holdings
where quarter='2020_Q3'
and symbol='AAPL') q3
left join (select * from holdings
where quarter='2020_Q4'
and symbol='AAPL') q4
on q3.institution_id=q4.institution_id
where
q3.shares>0
and (q4.shares=0 or q4.shares is null)
附加信息:
Table 'holdings' 被 'quarter' 分割。
指数是在 'institution_id'、'symbol' 和 'quarter' 上创建的。
列的组合(institution_id、符号、四分之一)是唯一的。
非常感谢任何帮助。
提前致谢。
您必须使用 window 函数引导以下方式:
select * from (
select
holdings.*,
-- use lead for retrieve previous quarter shares
lead(shares) over (partition by institution_id, symbol order by quarter desc) previous_quarter
from holdings
where symbol = 'AAPL'
) copmarsion
-- limit records where shares less when previous_quarter
where shares < coalesce(previous_quarter, 0);
SELECT COUNT(*) AS "soldCount",SUM(T1.shares) as "soldShares" FROM holdings T1
LEFT JOIN holdings T2 ON T1.institution_id = T2.institution_id
WHERE (T1.quarter = '2020_Q3' AND T1.symbol = 'AAPL') OR (T2.quarter = '2020_Q4' AND T2.symbol = 'AAPL')
AND T1.shares > 0 AND (T2.shares = 0 OR T2.shares IS NULL)
通常 EXISTS
比 LEFT
连接执行得更好:
SELECT COUNT(*) AS "soldCount",
SUM(q3.shares) AS "soldShares"
FROM holdings q3
WHERE q3.quarter='2020_Q3' AND q3.symbol='AAPL' AND q3.shares>0
AND NOT EXISTS (
SELECT 1
FROM holdings q4
WHERE q4.institution_id=q3.institution_id
AND q4.quarter='2020_Q4' AND q4.symbol='AAPL'
AND q4.shares<>0
)
我只会使用聚合。自己获取机构:
select symbol, institution, sum(shares) as q3_shares
from hodings
where quarter in ('2020_Q3', '2020_Q4') and
symbol = 'AAPL'
group by symbol, institution
having sum(shares) filter (where quarter = '2020_Q3') = sum(shares) and
sum(shares) > 0;
having 子句的逻辑是:“所有份额都在'2020_Q3'中并且至少有一个份额”。
然后如果你想要总数,第二级聚合:
select symbol, count(*), sum(q3_shares)
from (select symbol, institution, sum(shares) as q3_shares
from hodings
where quarter in ('2020_Q3', '2020_Q4') and
symbol = 'AAPL'
group by symbol, institution
having sum(shares) filter (where quarter = '2020_Q3') = sum(shares) and
sum(shares) > 0
) si;
我们有一个叫 'holdings' 的 table。 包含各季度金融机构持股数量信息。
其中有以下列:
institution_id | symbol | shares | quarter |
---|---|---|---|
1 | AAPL | 0 | 2020_Q4 |
2 | TSLA | 200000 | 2020_Q4 |
1 | AAPL | 100000 | 2020_Q3 |
我们要计算编号。在特定季度出售了特定公司(用符号表示)的持股的机构的数量。 我们目前有这样的查询,但我认为它可以改进。
select count(*) as "soldCount",sum(q3.shares) as "soldShares" from
(select * from holdings
where quarter='2020_Q3'
and symbol='AAPL') q3
left join (select * from holdings
where quarter='2020_Q4'
and symbol='AAPL') q4
on q3.institution_id=q4.institution_id
where
q3.shares>0
and (q4.shares=0 or q4.shares is null)
附加信息: Table 'holdings' 被 'quarter' 分割。 指数是在 'institution_id'、'symbol' 和 'quarter' 上创建的。 列的组合(institution_id、符号、四分之一)是唯一的。
非常感谢任何帮助。 提前致谢。
您必须使用 window 函数引导以下方式:
select * from (
select
holdings.*,
-- use lead for retrieve previous quarter shares
lead(shares) over (partition by institution_id, symbol order by quarter desc) previous_quarter
from holdings
where symbol = 'AAPL'
) copmarsion
-- limit records where shares less when previous_quarter
where shares < coalesce(previous_quarter, 0);
SELECT COUNT(*) AS "soldCount",SUM(T1.shares) as "soldShares" FROM holdings T1
LEFT JOIN holdings T2 ON T1.institution_id = T2.institution_id
WHERE (T1.quarter = '2020_Q3' AND T1.symbol = 'AAPL') OR (T2.quarter = '2020_Q4' AND T2.symbol = 'AAPL')
AND T1.shares > 0 AND (T2.shares = 0 OR T2.shares IS NULL)
通常 EXISTS
比 LEFT
连接执行得更好:
SELECT COUNT(*) AS "soldCount",
SUM(q3.shares) AS "soldShares"
FROM holdings q3
WHERE q3.quarter='2020_Q3' AND q3.symbol='AAPL' AND q3.shares>0
AND NOT EXISTS (
SELECT 1
FROM holdings q4
WHERE q4.institution_id=q3.institution_id
AND q4.quarter='2020_Q4' AND q4.symbol='AAPL'
AND q4.shares<>0
)
我只会使用聚合。自己获取机构:
select symbol, institution, sum(shares) as q3_shares
from hodings
where quarter in ('2020_Q3', '2020_Q4') and
symbol = 'AAPL'
group by symbol, institution
having sum(shares) filter (where quarter = '2020_Q3') = sum(shares) and
sum(shares) > 0;
having 子句的逻辑是:“所有份额都在'2020_Q3'中并且至少有一个份额”。
然后如果你想要总数,第二级聚合:
select symbol, count(*), sum(q3_shares)
from (select symbol, institution, sum(shares) as q3_shares
from hodings
where quarter in ('2020_Q3', '2020_Q4') and
symbol = 'AAPL'
group by symbol, institution
having sum(shares) filter (where quarter = '2020_Q3') = sum(shares) and
sum(shares) > 0
) si;