MySQL 连接两个潜在的字段名称

标签 mysql sql join left-join

对于我正在开发的一个网站,我的任务是实现一个私有(private)消息系统。 我的基本场景是,数据库中有多个消息条目,每个条目包含一个发送者和一个接收者。然而,“当前用户”应该能够看到这两条消息,因为它们都与他相关。 问题是,我只对其他用户的数据感兴趣,而不是我自己的数据。但“当前用户”既可以是发件人,也可以是收件人。

我在这里的查询完成了这项工作,但它并不优雅。我加入两个用户,然后使用 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 个单个表中以便在连接中重用?否则,这是否会消耗性能(连接我不需要的表?)。或者我应该在应用程序本身中将它们分开?

提前致谢!

最佳答案

看到我不允许编辑其他答案,该答案部分正确。 我的答案是基于 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

关于MySQL 连接两个潜在的字段名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21484966/

相关文章:

mysql - 使用 INNER JOIN 后搜索 SQL 查询

mysql - 在连接条件下使用函数,是否会因为缺少可用索引而导致全表扫描?

mysql - 高级 SQL 选择查询

mysql - 以下两个条件有什么区别? 1. 其中 ABC> ='00' 且 ABC< ='ZZ' 2. 其中 ABC> ='0' 且 ABC< ='Z'

sql - MySQL仅从一张表中查询出现在某一类别表中的产品

python - 使用pymysql插入表

sql - 一旦表被删除,索引会发生什么?

SQL 检查一组日期是否在指定的日期范围内

mysql - 根据属于组集的不同列的最大值创建排名列

MySQL : how to synchronize 2 tables structures when adding new fields?