简体   繁体   中英

PostgreSQL: Outer and self join

I want to do an outer join on the same table, but I'm getting unexpected results.

This is what my "stock" table looks like:

price_timestamp,            security,   price_type, open,  high, low,  close
"2014-05-01 00:00:00-07";"SPY US EQUITY";"ASK";     188.54;188. 57;188.54;188.57
"2014-05-01 07:59:00-07";"SPY US EQUITY";"ASK";     188.72;188. 72;188.72;188.72
"2014-05-01 08:01:00-07";"SPY US EQUITY";"ASK";     188.71;188. 72;188.71;188.72
"2014-05-01 13:30:00-07";"SPY US EQUITY";"TRADE";   188.22;188. 27;188.21;188.26
"2014-05-01 13:31:00-07";"SPY US EQUITY";"TRADE";   188.27;188. 35;188.26;188.35
...

price_type can be BID, ASK or TRADE. I want a query that returns price_timestamp, security, bid price (which would be close price where price_type = 'BID'), and trade price (which would be close price where price_type = 'TRADE).

This is what I have:

SELECT b.price_timestamp, b.security, b.close AS bid, t.close AS trade
  FROM stock b
  FULL OUTER JOIN stock t
    ON b.price_timestamp = t.price_timestamp
   AND b.security = t.security
 WHERE b.price_type = 'BID'
   AND t.price_type = 'TRADE'

This returns 19370 records. There are 40147 bid prices, 19399 trade prices, so I'm expecting at least max(40147, 19399) = 40147 records. At a glance, it looks it's returning an INNER JOIN.

I've also tried moving "b.security = t.security" in the ON cluse to the WHERE clause -- no luck.

You're getting fewer records because on the where clause you're referring both aliases 'b'& 't'. So, it is filtering only those joined records where b.price_type = 'BID' and t.price_type = 'TRADE'

Try moving the where conditions into the joins

For example:

SELECT b.price_timestamp, b.security, b.close AS bid, t.close AS trade
  FROM stock b
  FULL OUTER JOIN stock t
    ON b.price_timestamp = t.price_timestamp
   AND b.security = t.security
   AND t.price_type = 'TRADE'
 WHERE b.price_type = 'BID'

This would return all records from alias 'b' where b.price_type = 'BID', and at least one record from alias 't'. If no matching records are found from 't', a null records will be returned.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM