views:

52

answers:

3

Hello. I have a activities page and a statusmessages page for each user.

In activities it contains what the users have done, such as being friends with someone, commented on pictures and so.

users_activities
id | uID | msg | date  

In users_statusmessages, I got the statusmessages, the user creates.

users_statuses
id | uID | message | date

uID is the user´s id.

Now i would like to select both of them and while{} them in one. Where they get sorted by date desc ( as the date in both tables is UNIX timestamp).

So something like WHERE uID = '$userID' ORDER BY date DESC

So example of how i wish it to look:

User: Today is a good day (message) (date: 1284915827) (users_statuses)
User have added as Jack as friend (msg) (date: 1284915811) (users_activities)
User: I have a hard day today (message) (date: 1284915801) (users_statuses)
User have commented on Jacks picture (msg) (date: 1284915776) (users_activities)

How should i do this the right way?

A: 

You're going to want to use a union

http://dev.mysql.com/doc/refman/5.0/en/union.html

This is untested...

(SELECT uID, msg as message, date from users_activities)
UNION
(SELECT uId, message, date from users_statuses) order by date desc limit 20

There are a lot more examples on that page

Galen
+2  A: 

You need to use the UNION operator:

  SELECT ua.msg, 
         ua.date,
         'activity' AS is_table
    FROM USERS_ACTIVITIES ua
   WHERE ua.uid = '{$userID}'
UNION ALL
  SELECT us.message, 
         us.date, 
         'status'
    FROM USERS_STATUSES us
   WHERE us.uid = '{$userID}'
ORDER BY `date`

UNION

UNION removes duplicates. UNION ALL does not remove duplicates, and is faster for it.

But the data types at each position in the SELECT must match. In the query provided, you can see that the date column is referenced in the second position. You'd get an error if the column order were reversed between the first and second query.

The ORDER BY is applied to the result of the UNION'd query in standard SQL. In MySQL, that includes the LIMIT clause. But MySQL also supports putting brackets around the UNION'd queries so you can use ORDER BY & LIMIT before the queries are UNION'd.

OMG Ponies
When im using this in a while($show = mysql_fetch_array($query)) im receiving: mysql_fetch_array() expects parameter 1 to be resource, boolean given in. This is because ORDER BY ua.date , how can i solve this?
Karem
@Karem: Typo on my part, see the update.
OMG Ponies
And while waiting for answer on the ORDER part, i tried echo $show["msg"] and it works well, gets all the user´s status, but when I do $show["message"], show anything.
Karem
just noticed when i do $show["msg"] it shows BOTH msg and messages like I wanted
Karem
@Karem: Yes, the column reference is based on the first of the UNION'd queries. Sorry, mentioned everything but that.
OMG Ponies
Ok, last thing i think, im trying to sort out WHERE `uID` = '$USER', but then i dont get any results. How is this wrong?
Karem
@Karem: Sorry, I missed that requirement. See the updated one.
OMG Ponies
@OMG Ponies; ty, OK almost there, just one last thing, how can i know if its from the status or activity? Example i want to make $show["status"] bold, if its a status, else if its a activity just display without having it bold. How can i check for that? Last question before accepting, thank you
Karem
@Karem: Add a column, with statically defined values. See the update, I labelled the column "is_table". You can check the value in PHP, and handle presentation accordingly.
OMG Ponies
So let me get this clear: I make a column called "activity" in users_activities and a column in users_statuses called "status" ? And then make a standardvalue "1" for it? And then after that, i check by doing if(isset($show["is_table"] == 1)) ? Sorry, if im asking too much
Karem
@Karem: Using what I provided, `$show['is_table'] == 'activity'` for knowing when to handle activities; `$show['is_table'] == 'status'` for statuses. You can change the value to be numeric if you like.
OMG Ponies
Yes ok, so standardvalue should be status/activity ?
Karem
OH my bad! I thought you want me to add an column in the table.. But now i understand what you did, thank you, accepted and +1!
Karem
@Karem: I should have said "derived column", sorry.
OMG Ponies
A: 

Something like this would do

SELECT act.*,status.* FROM users_activities act, users_statuses status WHERE act.id = status.id AND status.id = '$UID' ORDER BY status.date,act.date DESC LIMIT 30

Spaced out for visual purposes:

SELECT
    act.*,status.*
FROM
    users_activities act,
    users_statuses status
WHERE
    act.id = status.id
AND
    status.id = '$UID'
ORDER BY 
    status.date,act.date DESC
LIMIT
    30
RobertPitt
You may have misread the question. There is no relationship between activities and statuses, as far as I can tell.
Extrakun