Reputation: 401
I have 3 MySQL tables representing: photos a user post, videos a user post, comments a user post and I need to view the 10 (20, 30, 40...) most recent activities by the user.
For example in photos table may be composed by:
user_id | photo_id | photo_path | photo_name | date_added
5 | 18 | /photos | pht_18.png | 2009-02-12
5 | 21 | /photos | pht_21.png | 2009-02-15
5 | 29 | /photos | pht_29.png | 2009-03-30
the videos table
user_id | video_id | video_url | date_added
5 | 36 | youtube.com/... | 2009-01-09
5 | 48 | youtube.com/... | 2009-02-18
5 | 90 | youtube.com/... | 2009-03-19
the comments table
user_id | comment_id | comment | date_added
5 | 6 | hi! | 2009-02-11
5 | 11 | great photo | 2009-02-13
5 | 19 | nice shot! | 2009-03-28
As you can see the 3 tables have different number of attributes, so how can I do the union? and while fetching the query result how can I understand to which table it belongs to?
So in the user profile page I'd like to show his recent activities of course ordered by DATE DESC this way:
2009-09-01: user posted a video
2009-11-02: user posted a comment
2009-12-02: user posted a photo
2009-13-02: user posted a comment
2009-15-02: user posted a photo
2009-18-02: user posted a video
2009-19-03: user posted a video
2009-28-03: user posted a comment
2009-30-03: user posted a photo
Can anyone help me please?
Upvotes: 9
Views: 5044
Reputation: 338208
Why do you have separate tables in the first place? That's probably a mistake in database design.
[EDIT: As it turned out through comments and a question edit, the OP had a valid reason to maintain three tables. Further advice about this removed.]
To solve your problem you can use UNION or UNION ALL:
(SELECT 'photo' AS item_type, date_added, user_id FROM photos)
UNION ALL
(SELECT 'video' AS item_type, date_added, user_id FROM videos)
UNION ALL
(SELECT 'comment' AS item_type, date_added, user_id FROM comments)
ORDER BY date_added DESC
Upvotes: 3
Reputation: 51110
Personally, I would make another table to store any activity. It would simplify things a lot and you could also keep track of deletions and other activities.
Upvotes: 3
Reputation: 17320
If it was me, I would just do a query to each table and select the N most recent items (order by date_added desc limit N), and then merge them in PHP. That way, you are protected in case you ever need to host the tables on separate physical machines.
You may also ask yourself why you need 3 tables. Perhaps 1 table with an activity_type column would be enough. That would probably make it easier to add more activity types later.
Upvotes: 1
Reputation: 655239
Do a UNION
on these tables:
(SELECT "photo" AS `table`, `date_added` FROM `photos` ORDER BY `date_added` LIMIT 10)
UNION
(SELECT "video" AS `table`, `date_added` FROM `videos` ORDER BY `date_added` LIMIT 10)
UNION
(SELECT "comment" AS `table`, `date_added` FROM `comments` ORDER BY `date_added` LIMIT 10)
ORDER BY `date_added` DESC
LIMIT 10;
Upvotes: 0
Reputation: 131570
A MySQL UNION query could work here:
(SELECT `user_id`, `date_added`, 'photo' AS `type` FROM `photos` WHERE `user_id` = uid) UNION
(SELECT `user_id`, `date_added`, 'video' AS `type` FROM `videos` WHERE `user_id` = uid) UNION
(SELECT `user_id`, `date_added`, 'comment' AS `type` FROM `comments` WHERE `user_id` = uid)
ORDER BY `date_added` DESC;
Then you'd wind up with a result set like
user_id | date_added | type
5 | 2009-01-03 | photo
5 | 2008-12-07 | video
5 | 2008-11-19 | comment
and so on. (actually you can leave user_id
out of the SELECT if you want, of course)
Upvotes: 11