在过去的几个小时里,我被这个问题所困扰,我非常需要有人来帮助我解决这个问题。我试图完成我的私人消息系统,但我在数据库表中迷失了自己。我为系统创建了三个表,它们如下:
CONVERSATION(**conversation_id**, subject)
CONVERSATION_MEMBER(**conversation_id**, **user_id**, conversation_last_view, conversation_deleted)
CONVERSATION_MESSAGE(**message_id**, conversation_id, user_id, message_date, message_text)
好的,所以在我的功能中获取特定用户的所有对话,我正在获取主题,日期,最后我想向他/她说话的用户显示。我写了以下查询:
SELECT
c.conversation_id,
c.conversation_subject,
MAX(cmes.message_date) AS conversation_last_reply,
FROM conversation c, conversation_member cmem, conversation_message cmes
WHERE c.conversation_id = cmes.conversation_id
AND c.conversation_id = cmem.conversation_id
AND cmem.user_id = {$_SESSION['user_id']}
AND cmem.conversation_deleted = 0
GROUP BY c.conversation_id
ORDER BY conversation_last_reply DESC
最后,我试着获取用户的名字和姓氏(对话中的其他用户),但我却迷失了自己如何做到这一点。我试图创建另一个函数来获取会话ID,同时循环查看第一个查询的结果,并返回用户的名字和姓氏,但它没有用完。
不过,对于用户我有另一张桌子......我想我没有必要告诉你。好的,谢谢。答案 0 :(得分:2)
$sql = "SELECT (user.forename, user.surname, other_fields...)
FROM conversation
INNER JOIN conversation_member
ON conversation.conversation_id = conversation_member.conversation_id
INNER JOIN conversation_message
ON conversation.conversation_id = conversation_message.conversation_id
INNER JOIN users_table /* replace this with the name of your user table */ AS user
ON user.user_id = conversation_member.user_id
WHERE user.user_id = :userid
AND conversation_member.conversation_deleted = 0
GROUP BY conversation.conversation_id;"
$query = $db->prepare($sql);
$query->bindParam(':userid', $userid, PDO::PARAM_INT);
$query->execute();
$results = $query->fetchAll();
$user = $results[0]["user"]; //stores array of user fields (forename, surname, etc)
答案 1 :(得分:1)
SELECT
c.conversation_id,
c.conversation_subject,
user.firstname,
user.lastname,
MAX(cmes.message_date) AS conversation_last_reply,
FROM conversation c, conversation_member cmem, conversation_message cmes, user_tablename user
WHERE c.conversation_id = cmes.conversation_id
AND c.conversation_id = cmem.conversation_id
AND cmem.user_id = {$_SESSION['user_id']}
AND cmem.conversation_deleted = 0
AND user.user_id_column = whatever.you_used_as_foriegn_key
GROUP BY c.conversation_id
ORDER BY conversation_last_reply DESC
假设列名称是那样的
答案 2 :(得分:1)
您需要再次加入“conversation_member”表,这一次,选择同一个conversation_id和message_id适用的其他用户ID:
SELECT
c.conversation_id,
c.conversation_subject,
MAX(cmes.message_date) AS conversation_last_reply,
cmem2.user_id AS other_user_id
CONCAT(usr_tbl.firstname, ' ', usr_tbl.lastname) AS other_user_name
FROM conversation c
JOIN conversation_member cmem
JOIN conversation_message cmes
JOIN conversation_member cmem2
JOIN users_table usr_tbl
ON c.conversation_id = cmes.conversation_id
AND c.conversation_id = cmem.conversation_id
AND cmem.user_id = {$_SESSION['user_id']}
AND cmem.conversation_deleted = 0
AND c.conversation_id = cmem2.conversation_id
AND cmem2.user_id = {$_SESSION['other_user_id']}
AND cmem2.conversation_deleted = 0
GROUP BY c.conversation_id
ORDER BY conversation_last_reply DESC
答案 3 :(得分:1)
如果您能够自己构建其余的查询,我不明白为什么您无法获取用户的名字和姓氏?
尝试以下方面:
SELECT cmem.user_id, u.first_name, u.last_name, c.conversation_id, c.conversation_subject, MAX(cmes.message_date) AS conversation_last_reply
FROM conversation c
INNER JOIN conversation_member cmem on c.conversation_id=cmem.conversation_id
INNER JOIN conversation_message cmes on c.conversation_id=cmes.conversation_id
INNER JOIN users u on u.user_id = cmem.user_id
WHERE cmem.user_id = {$_SESSION['user_id']} AND cmem.conversation_deleted = 0
GROUP BY cmem.user_id, u.first_name, u.last_name, c.conversation_id, c.conversation_subject
现在,我认为您还应该重新考虑您的数据库结构,以便不需要所有这些连接。我看到几个问题。一,您的数据库似乎过度规范化了。为什么你有一个单独的“对话”表,只有两个字段,会话ID和主题?在我见过的任何消息系统中,主题始终可见,因此您始终必须加入会话表才能获得主题字段。无论如何,conversation_id在每个其他表中。只需将主题字段添加到消息表中,并删除会话表,如果它只是持有,则规范化并不总是一件好事。
其次,为什么要为已删除的邮件设置标志而不是仅删除它们?我也从未见过一个允许我恢复已删除邮件的邮件系统。至少,如果你想因为某种原因想要保留它们,你应该将它们移动到一个存档表中,这样你运行的主表选择关闭就不必处理通过无意义解析的性能损失“删除“条目。
最后,对话会员表是什么?根据我的解释,它应该代表对话的成员,因为它有user_id。为什么对话的一个成员会出现对话删除标志?如果它应该在对话表中。随着这一改进,其中唯一的领域是conversation_last_view,这真的没有人关心。更重要的是conversation_last_post,它可以很容易地从线程中发布的最后一条消息的时间戳中获得。
最终,如果您只想查看附加到查询中的名字和姓氏,就像加入users表并显示这两个条目一样简单。我提供的SQL查询应该让你关闭,如果它不能直接工作,我太懒了复制你的数据库并自己尝试。但是,我认为你应该真正考虑数据库的整体设计,这样你就不会遇到不必要的性能问题。
答案 4 :(得分:0)
要回答以下问题:在对话中查找所有用户,请减少当前用户:
SELECT (users.forename, users.surname)
FROM conversation_members AS members
INNER JOIN users_table AS users
ON members.user_id = users.user_id
WHERE members.conversation_id = :conversationid
AND NOT users.user_id = :userid
:userid
是当前用户,而:conversationid
是相关对话。