Reputation: 171
I have a transactions table which has shows various transactions made by several accounts. Some make only one, others more than that. At the moment the SQL I have prints out the first purchase of each account but i need it to print out the second made by each account
SELECT account_id
, purchase_date as second_purchase
, amount as second_purchase_amount
FROM Transactions t
WHERE purchase_date NOT IN (SELECT MIN(purchase_date)
FROM Transactions m
)
GROUP BY account_id
HAVING purchase_date = MIN(purchase_date);
What needs to change that the second purchase date and amount are chosen? I tried adding in a count for the account_id but it was giving me the wrong value.
Upvotes: 0
Views: 479
Reputation: 49260
You can use variables to assign row numbers and get the 2nd purchase.
SELECT account_id,purchase_Date,amount
FROM (
SELECT account_id
,purchase_date
,amount
--, @rn:=IF(account_id=@a_id and @pdate <> purchase_date,@rn+1,1) as rnum
,case when account_id=@a_id and @pdate <> purchase_date then @rn:=@rn+1
when account_id=@a_id and @pdate=purchase_date then @rn:=@rn
else @rn:=1 end as rnum
, @pdate:=purchase_date
, @a_id:=account_id
FROM Transactions t
CROSS JOIN (SELECT @rn:=0,@a_id:=-1,@pdate:='') r
ORDER BY account_id, purchase_date
) x
WHERE rnum=2
Explanation of how it works:
@rn:=0,@a_id:=-1,@pdate:=''
- Declare 3 variables and initialize them, @rn for assigning the row numbers, @a_id to hold the account_id and @pdate to hold the purchase_date.
For the first row (ordered by account_id and purchase_date), account_id and @a_id, @pdate and purchase_date will be compared. As they wouldn't be equal, the when
conditions fail and the else
part would assign @rn=1. Also, the variable assignment happens after this. @aid and @pdate would be updated to current row's values. For the second row, if they are the same account and on a different date the first when
condition will be executed and the @rn will be incremented by 1. If there are ties the second when
condition would be executed and the @rn remains the same. You can run the inner query to check how the variables are assigned.
Upvotes: 1
Reputation: 10807
Number the rows and choose RowNumber = 2
select *
from (
select
@rn := case when @account_id = account_id then @rn + 1 else @rn := 1 end as RowNumber,
@account_id := account_id as account_id,
purchase_date
from
(select @rn := 1) x,
(select @acount_id :=account_id as account_id, purchase_date
from Transactions
order by account_id, purchase_date) y
) z
where RowNumber = 2;
Upvotes: 0