简体   繁体   中英

How to join two mysql tables that are mostly different, and sort by two columns at once?

I apologize for the improperly worded title; couldn't think of a better one.

I have an app that sends and receives messages. I have two tables, one for sent, one for received:

Sent:

id
status
sent_date
user_id
sent_message
sent_from
sent_to
another_field1
another_field2
comments

Received:

id
received_date
user_id
received_message
received_from
received_to
another_field3
another_field4
comments

I'm trying to display a conversation thread based on these two tables. I need to JOIN the two by the user_id, WHERE received.received_from=sent.sent_to AND received.received_to=sent.sent_from AND sent.status=1 [means it was sent], then sort them by both the two date columns--so the messages are displayed in conversation order.

I saw other similar questions that used a union to do this, but I'm not sure that would work in my case due to different columns. My display, done in PHP, would be something like this:

Conversation with {sent_to}, ordered by date:

{sent_date} From me: {sent_message}
{received_date} From {received_from}: {received_message}
{received_date} From {received_from}: {received_message}
{sent_date} From me: {sent_message}

Also, I realize that I may have structured the database inefficiently. I'm open to suggestions on how to better optimize the structure and how it works. Thank you.

EDIT: I just tried doing Alain Collins's suggestion, but I'm having trouble figuring out how to separate the sent fields from the received fields. I'm really trying to put the two tables together, but not combining the actual fields. Here's what I have so far, which is totally wrong:

SELECT *,
     case when sent.sent_date is not null then sent.sent_date 
     else received.received_date end AS date 
FROM sent JOIN received ON (received.user_id = sent.user_id)
WHERE sent.user_id = ".$_SESSION['id']." ORDER BY date ASC

This is joining the received and sent messages into one row. I still need them separated. Any tips on how to do this? Would it perhaps be somewhat easier to have both sent and received message in a single table?

EDIT 2: To clarify, I want the columns from both tables separate. Meaning, the ROWS returned should only have either sent columns or received columns, but the rows should be returned in order of the date, as mentioned above. So I'd get rows something like this:

Row 1: Array(Date, Sent_Message, Sent_From)
Row 2: Array(Date, Received_Message, Received_From)
Row 3: Array(Date, Received_Message, Received_From)
Row 4: Array(Date, Sent_Message, Sent_From)

So the only two thing in common with the two tables is 1) the user_id having the conversation and 2) the dates. The dates must somehow be combined because they are currently "sent_date" and "received_date".

You might have a an easier go of it if you structure your tables around a 'thread_id' instead of trying to match up by 'sent_to=recd_from'. When a new message is created (ie not in response) create a new thread with a new message id. Then any response to this will reference the original thread_id and you can sort the responses by message id to get the order of the thread.

Create a column that contains the date from the underlying table and sort by that:

select case
  when sent.sent_date is not null then sent.sent_date
  else received.received_date
end as message_date
...
order by message_date;

I figured out the proper query for what I'm trying to do:

(SELECT sent_date AS date, sent_message, sent_from 
FROM sent WHERE user_id = ".$_SESSION['id'].") 
UNION ALL (SELECT received_date AS date, received_message, received_from 
FROM received WHERE user_id = ".$_SESSION['id'].") 
ORDER BY date ASC

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM