2

I have a one to many relationship: User has many Payments. I am trying to find a query that gets the first payment of each user(using created_at from the payments table).

I have found a similar question with an SQL response, but I have no idea how to write it with Active Record.

how do I query sql for a latest record date for each user

Quoting the answer:

select t.username, t.date, t.value
from MyTable t
inner join (
    select username, max(date) as MaxDate
    from MyTable
    group by username
) tm on t.username = tm.username and t.date = tm.MaxDate

For me, it would be min instead of max.

Thank you :)

Community
  • 1
  • 1
Ioana Surdu Bob
  • 139
  • 1
  • 9

6 Answers6

1

Try this one for POSTGRES

Payment.select("DISTINCT ON(user_id) *").order("user_id, created_at ASC")

And For SQL

Payment.group(:user_id).having('created_at = MAX(created_at)')
Fakhir Shad
  • 1,071
  • 8
  • 20
0

If I'm going to answer the question above with: (I don't based on given raw SQL)

User has many Payments. I am trying to find a query that gets the first payment of each user(using created_at from the payments table).

Let say:
# Assumed to have a Single User, as reference
user = User.first

# Now, get first payment (from Payment model)
user.payments.last
# .last since it will always get the first created row by created_at.

If I fully understand what you're trying to do. I'm don't know why you need max or min date?

aldrien.h
  • 3,437
  • 2
  • 30
  • 52
0

What about this?

If you want first payment of each user

dates = Payment.group(:user_id).minimum(:created_at).values
payments = Payment.where(created_at: dates)

From payment you can find user too.

I think you have username as foreign key, you can change accordingly. :) Let me know if you face any issue, as I tested it works.

I know this answer is not the best, but it will work even or transactions with milliseconds difference, as rails saves date(created_at and updated_at) with ms level.

kamal
  • 996
  • 15
  • 25
0

I am sorry for not replying to everything, but after multiple tests, this is the quickest answer (in run time) I came with:

Payment.where(:id => Payment.group(:user_id).pluck(:id))

I am saying it might not be the quickest way because I am using a sub query. I am getting the unique values and getting the ID's:

Payment.group(:user_id).pluck(:id)

Then I am matching those ID's.

The downside of this is that it won't work reversed, for getting the last payment.

There was also a possibility to use group_by and map but, since map is coming from ruby, it is taking much more time.

Ioana Surdu Bob
  • 139
  • 1
  • 9
-1

I'm not sure but try this :

In your controller :

  def Page
    @payments = Payment.first
  end

in your html.erb :

<% @payments.each do |payment| %>
  <p> <%= payment.amount %> </p>

Hope this help !

-1
Record.association.order(:created_at).first
Lucas Ferronato
  • 119
  • 1
  • 9