php - MySQL 选择 JOIN 3 个表

标签 php mysql

我有三个基本表:

tblUsers:

    usrID     usrFirst     usrLast
      1        John          Smith
      2        Bill          Jones
      3        Jane          Johnson

pm_data:

id     date_sent              title          sender_id  thread_id         content
2   2009-07-29 18:46:13     Subject 1           1         111        Message 2!
3   2009-07-29 18:47:21     Another Subject     1         222        Message 3!

pm_info:

id  thread_id   receiver_id  is_read
1     111           2            0
2     111           3            0
3     222           2            0
4     222           3            0

本质上,我想做的是创建一个收件箱。

因此,如果 usrID 2 (Bill Jones) 打开他的收件箱,他将看到他 2 条未读(因此是“已读”列)消息(线程 #111 和 #222)。

基本上,我需要知道如何设置我的 SELECT 语句以连接所有三个表(pm_data 和 pm_info 之间的关系带来了消息信息,而 tblUsers 和 pm_data 之间的关系带来了“显示名称”发件人),以在顶部显示最近的(按时间戳记?)线程。

因此,我们会看到这样的东西:

<?php  $usrID = 2;  ?>

<table id="messages">
  <tr id="id-2">
  <td>
   <span>
     From: John Smith
    </span>
    <span>2009-07-29 18:47:21</span>
  </td>
 <td>
 <div>Another subject</div>
 </td></tr>
<tr id="id-1">
 <td>
   <span>
     From: John Smith
   </span>
   <span>2009-07-29 18:46:13</span>
</td>
 <td>
   <div>Subject 1</div>
 </td></tr>
 </table>

希望这是有道理的!感谢您的帮助!

编辑:这是我的最终答案:

我听取了lc的建议,根据id建立了两个表的关系(在pm_info中添加了一个名为'message_id'的列)。

然后,稍微调整一下 MySQL 语句,得出以下结论:

SELECT pm_info.is_read, sender.usrFirst as sender_name,
pm_data.date_sent, pm_data.title, pm_data.thread_id
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
WHERE pm_data.date_sent IN(SELECT MAX(date_sent) FROM pm_data WHERE pm_info.message_id = pm_data.id GROUP BY thread_id) AND pm_info.receiver_id = '$usrID' ORDER BY date_sent DESC

这似乎对我有用(到目前为止)。

最佳答案

您需要两个连接。像下面这样的东西应该让你开始(虽然我不是 100% 理解 pm_datapm_info 之间的关系):

SELECT pm_info.is_read, sender.usrFirst + ' ' + sender.usrLast as sender_name, 
    pm_data.date_sent, pm_data.title, pm_data.thread_id
FROM pm_info
INNER JOIN pm_data ON pm_info.thread_id = pm_data.thread_id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = tblUsers.usrID
WHERE pm_info.receiver_id = @USER_ID /*in this case, 2*/
ORDER BY pm_data.date_sent DESC

我假设 pm_datapm_info 之间的关系是线程 ID。如果不是,您应该能够根据需要调整上述内容。我也在这里按发送日期排序,但它不会将线程放在一起。我不确定您是否希望将它们放在一起,这取决于您表达问题的方式。


如果您想将线程放在一起,您将需要更复杂的查询:

SELECT pm_info.is_read, sender.usrFirst + ' ' + sender.usrLast as sender_name, 
    pm_data.date_sent, pm_data.title, pm_data.thread_id
FROM pm_info
INNER JOIN pm_data ON pm_info.thread_id = pm_data.thread_id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = tblUsers.usrID
INNER JOIN (SELECT thread_id, MAX(date_sent) AS max_date
            FROM pm_data
            GROUP BY thread_id) AS most_recent_date 
           ON pm_data.thread_id = most_recent_date.thread_id
WHERE pm_info.receiver_id = @USER_ID /*in this case, 2*/
ORDER BY most_recent_date.max_date DESC, pm_data.thread_id, 
    pm_data.date_sent DESC

此查询使用子选择来查找每个线程的最新修改日期,然后首先按此进行排序。

关于php - MySQL 选择 JOIN 3 个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1204217/

相关文章:

用于数学运算的 PHP 正则表达式

php - 从 Android 手机上传图片到笔记本电脑需要太长时间,最后上传时显示“Windows 照片查看器无法显示,因为文件为空”

php - 一般和特定(大学域)的最佳电子邮件验证功能?

php - num_rows 和 count() 不匹配 - php

mysql - 如何在按其中一个表过滤的同时从另一个表返回产品及其所有属性

mysql order by 不能与 group by 一起使用

mysql - SQL查询不同记录

mysql - 将平均值加到平均值

mysql - 如何编写这个 MySQL 查询?

php - json 和 php 问题