I have a simple relationship between User
and Donations
in that a user has many donations, and a donation belongs to a user. What I'd like to do is get a list of users, ordered by the most recent donations.
Here's what I'm trying:
First I want to get the total number of uniq users, which is working as expected:
> User.joins(:donations).order('donations.created_at').uniq.count
(3.2ms) SELECT DISTINCT COUNT(DISTINCT "users"."id") FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id"
=> 384
Next, when I remove the count
method, I get an error that "ORDER BY expressions must appear in select list":
> User.joins(:donations).order('donations.created_at').uniq
User Load (0.9ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id" ORDER BY donations.created_at
PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...ON "donations"."user_id" = "users"."id" ORDER BY donations....
Then I tried fixing the Postgres error by explicitly setting the SELECT clause which at first glance appears to work:
> User.select('DISTINCT "users".id, "users".*, "donations".created_at').joins(:donations).order('donations.created_at')
User Load (17.6ms) SELECT DISTINCT "users".id, "users".*, "donations".created_at FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id" ORDER BY donations.created_at
However, the number of records returned does not take into account the DISTINCT statement and returns 692 records:
> _.size
=> 692
How do I get the expected number of results (384) while also sorting by the donation's created_at timestamp?
DISTINCT is for all the columns in the select clause, which means all columns combined will be used to get distinct rows. TOP X will only select the number of rows mentioned in X .
The SQL SELECT DISTINCT Statement The SELECT DISTINCT statement is used to return only distinct (different) values. Inside a table, a column often contains many duplicate values; and sometimes you only want to list the different (distinct) values.
You can use CTE to get the distinct values of the second table, and then join that with the first table. You also need to get the distinct values based on LastName column. You do this with a Row_Number() partitioned by the LastName, and sorted by the FirstName.
The SQL DISTINCT keyword is used in conjunction with the SELECT statement to eliminate all the duplicate records and fetching only unique records. There may be a situation when you have multiple duplicate records in a table.
Try this:
User.select('users.*,MAX(donations.created_at) as most_recent_donation').
joins(:donations).order('most_recent_donation desc').group('users.id')
I suppose an user has many donations, this would select the most recent created donation and would select distinct users filtering by their id.
I have not tested this though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With