Reputation: 693
I have an issue with my SQL query, I try to join two tables, but as result have duplicated lines.
There is my database schema:
# messages
belongs_to :user
belongs_to :request
# requests
has_many :messages
belongs_to :expense
I have an polimorphic association between my expenses and requests tables.
And this my query:
Expense.
joins('LEFT JOIN requests ON expenses.id = requests.integration_id').
joins('LEFT JOIN messages ON requests.id = messages.request_id').
where('expenses.id IN (?)', @expenses_id).
select('DISTINCT messages.user_id AS user_id').
group('messages.user_id, expenses.id')
I get all expenses duplicated when I try to joins messages
table.
What happen?
EDIT:
With this query is same result:
Expense.
joins('LEFT JOIN requests ON expenses.id = requests.integration_id').
joins('LEFT JOIN messages ON requests.id = messages.request_id').
where('expenses.id IN (?)', @expenses_id).
select('DISTINCT messages.user_id AS user_id').
group('messages.user_id')
EDIT 2:
When I try this:
Expense.
joins('LEFT JOIN requests ON expenses.id = requests.integration_id').
count(:id)
#=> 45
But when I join messages
Expense.
joins('LEFT JOIN requests ON expenses.id = requests.integration_id').
joins('LEFT JOIN messages ON requests.id = messages.request_id').
count(:id)
#=> 93
Upvotes: 1
Views: 62
Reputation: 693
For solve this issue, I needed adding specific select on my JOIN
. Because, when I JOIN
the messages
table, I get many messages with same request_id
.
SELECT messages.user_id, SUM(expenses.total_in_home_currency)
FROM expenses
INNER JOIN requests ON expenses.id = requests.integration_id
INNER JOIN
(SELECT DISTINCT(messages.request_id), messages.user_id FROM messages) messages
ON requests.id = messages.request_id
WHERE expenses.id IN (76)
GROUP BY messages.user_id
Upvotes: 0
Reputation: 2166
OK I think I know the problem:
Rail's ActiveRecord will translate the field result into the model's attributes, and ignore anything outside. So let's say you have model A
with attribute b, c, d
. And your join result is:
| b | c | d | e | f |
| 1 | 2 | 3 | 1 | 2 |
| 1 | 2 | 3 | 2 | 1 |
| 1 | 2 | 3 | 2 | 2 |
Then you group by b
and e
| b | c | d | e | count(f) |
| 1 | 2 | 3 | 1 | 1 |
| 1 | 2 | 3 | 2 | 2 |
This will create 2 records since the query result returns 2 rows, but they are exactly the same when translate into model A (b = 1, c = 2, d = 3).
In your case, message.user_id
is the field causing this.
Remove it from group clause will fix the problem, but I don't know for sure what do you want message.user_id
to be used for.
Upvotes: 1