In a PostgreSQL 9.5.3 DB, I have a credit_card_balances
table referencing a persons
table which tracks the balances of various credit cards associated to a particular person:
CREATE TABLE persons (
id serial PRIMARY KEY,
name text
);
CREATE credit_card_balances (
id serial PRIMARY KEY,
card_provider text,
person int REFERENCES persons,
balance decimal,
timestamp timestamp
);
Example row for credit_card_balances
:
id | card_provider | person | balance | timestamp
123 | visa | 1234 | 1.00 | 16-07-26 17:00
I need to retrieve the collection of people who have both a 'visa' and an 'amex' card, such that the most recent balance on the 'visa' card is larger than the most recent balance on the 'amex' card.
For each (person, card_provider)
there may be up to around 100 rows in the table. Ideally, the output columns would be:
person, provider1_balance, provider2_balance, provider1_timestamp, provider2_timestamp
I know that I can do something like
SELECT DISTINCT ON (card_provider) *
FROM credit_card_balances
WHERE person=1234
ORDER BY card_provider, timestamp DESC;
to get the most recent balances for each card for a particular person. But I'm not sure how to do that over all people and verify the conditions above, or if this is even the correct approach.
Edit: AS partially suggested in an answer, I can also do something like
SELECT * from credit_card_balances b1, credit_card_balances b2
WHERE b1.person = b2.person
AND (b1.card_provider = 'amex'
AND b1.timestamp in
(SELECT MAX(time_stamp)
FROM credit_card_balances
WHERE card_provider = 'amex'))
AND (b2.card_provider = 'visa'
AND <... same as above>)
AND b1.balance > b2.balance;
But I noticed that this leads to horrible performance. So I think this isn't such a good option.