I have query that selects all users based on their sum of donation from another table and orders it by the sum of their donations.
But I would also like to select each user's last 2 comments where comment type is donation_comment by joining the them together with a space. And to be also able to search by user comments. If I specify where comment_text contains 'comment three' then only 1 entry would show for Sergey Brin.
I can't seem to figure out how to pull in their last comments and add where condition based on it.
So the result would be this
Array
(
[0] => stdClass Object
(
[id] => 2
[username] => Sergey Brin
[donation] => 500
[last_comments] => comment four comment three
)
[1] => stdClass Object
(
[id] => 1
[username] => Larry Page
[donation] => 400
[last_comments] => comment five comment two
)
)
Here's my current query
SELECT
users.id,
users.username,
sum(donations.donation) as donation
from
users
inner join donations
on users.id = donations.user_id
where
users.username like '%r%'
group by
users.id,
users.username
having
sum(donations.donation) >= 400
order by
donation desc
users table
id | username |
1 Larry Page
2 Sergey Brin
donations table
id | user_id | donation | date |
1 1 100 2019-02-12
2 1 200 2019-02-13
3 2 500 2019-01-15
4 1 100 2019-04-10
user_comments table
id | user_id | comment_text | type |
1 1 comment one donation_comment
2 1 comment two donation_comment
3 2 comment three donation_comment
4 2 comment four donation_comment
5 1 comment five donation_comment
I would make a subquery from your user_comments table where you limit the number of comments per user_id to 2. Then you can use string_agg()
to concatinate the comments
Try this:
SELECT
users.id,
users.username,
sum(donations.donation) as donation,
string_agg(comment_text, ', ') as comments
from
users
inner join donations
on users.id = donations.user_id
inner join (
SELECT* from user_comments
group by user_id
limit 2
) as last2_don on users.id = last2_don.user_id
where
users.username like '%r%'
group by
users.id,
users.username
having
sum(donations.donation) >= 400
order by
donation desc
A lateral join is a very reasonable approach:
select u.id, u.username,
sum(d.donation) as donation,
uc.comments_2
from users u inner join
donations d
on u.id = d.user_id left join lateral
(select string_agg(comment_text, '; ') as comments_2
from (select uc.*
from user_comments uc
where uc.user_id = u.id and
uc.type = 'donation_comment';
order by uc.id desc
limit 2
) c
) uc
on 1=1
where u.username like '%r%'
group by u.id, u.username, uc.comments
having sum(d.donation) >= 400
order by sum(donation) desc;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.