对于我正在研究的网站,我的任务是实施私人消息系统。 我的基本方案是,数据库中有几个消息条目,每个条目包含一个发送者和一个接收者。但是,“当前用户”应该能够看到这两个消息,因为它们都与他相关。 问题是,我只对其他用户的数据感兴趣,而不是我自己的数据。但“当前用户”既可以是发件人也可以是收件人。
我在这里的查询完成了这项工作,但它并不优雅。我正在加入这两个用户,然后决定使用IF我应该得到哪些数据。
SELECT
IF(m.sender = ?, 1, 0) AS isself,
IF(m.sender = ?, u_recipient.id, u_sender.id) AS other_id,
IF(m.sender = ?, u_recipient.displayName, u_sender.displayName) AS other_name,
IF(m.sender = ?, u_recipient_avatar.url, u_sender_avatar.url) AS other_avatar,
m.text AS text
FROM messages AS m
LEFT JOIN user AS u_sender
ON u_sender.id = m.sender
LEFT JOIN avatars AS u_sender_avatar
ON u_sender_avatar.id = u_sender.avatarId
LEFT JOIN user AS u_recipient
ON u_recipient.id = m.recipient
LEFT JOIN avatars AS u_recipient_avatar
ON u_recipient_avatar.id = u_recipient.avatarId
WHERE ( m.sender = ? OR m.recipient = ? )
AND UNIX_TIMESTAMP(m.timestamp) > ?
ORDER BY m.timestamp ASC
LIMIT 100
所以基本上,我的问题是,有没有更优雅的方式这样做?将发件人/收件人int存储到1个单独的表中以便在连接中重用?否则,这是一个性能困难(加入我不需要的表?)。或者我应该在应用程序本身中处理这些问题吗?
提前致谢!
答案 0 :(得分:0)
如下:
SELECT isself, other_id, u.displayName AS other_name, a.url AS other_avatar, text
FROM
(
SELECT 0 AS isself, m.sender AS other_id, m.timestamp, m.text
FROM messages AS m
WHERE m.recipient = ?
UNION
SELECT 1 AS isself, m.recipient AS other_id, m.timestamp, m.text
FROM messages AS m
WHERE m.sender = ?
) AS d
LEFT JOIN user AS u
ON u.id = d.other_id
LEFT JOIN avatars AS a
ON a.id = u.avatarId
WHERE UNIX_TIMESTAMP(timestamp) > ?
LIMIT 100
如果始终在用户表中找到邮件的发件人和收件人ID,则应将“LEFT JOIN user”更改为内部联接 - “JOIN user”。如果每个用户都有一个头像条目,那么该左连接也应该更改为内连接。
答案 1 :(得分:0)
看到我不被允许编辑其他答案,这是部分正确的。 我的答案是基于Ben的,但是删除了语法错误。
SELECT d.isself, other_id, u.displayName AS other_name, a.url AS other_avatar, text
FROM
(
SELECT 0 AS isself, m.sender AS other_id, m.timestamp, m.text
FROM messages AS m
WHERE m.recipient = ?
UNION
SELECT 1 AS isself, m.recipient AS other_id, m.timestamp, m.text
FROM messages AS m
WHERE m.sender = ?
) AS d
LEFT JOIN user AS u
ON u.id = d.other_id
LEFT JOIN avatars AS a
ON a.id = u.avatarId
WHERE UNIX_TIMESTAMP(timestamp) > ?
ORDER BY m.timestamp ASC
LIMIT 100