使用UNION和SORT的MySql查询

时间:2013-07-22 15:04:10

标签: mysql sql join union

实际上我正在尝试创建一个像FB(消息)这样的会话界面,并且为此,使用sql查询来获取已经与用户交谈过的所有人。 我需要他按照降序排列的用户的id, 就像A与B和C聊天一样。然后B和C将是该查询的结果,B将首先出现因为A最近与B聊天。

我的'消息'表结构是: http://www.softnuke.com/me/files/DB.png

这是FB的例子: http://www.softnuke.com/me/files/msg.png

这是我的错误查询,需要修复:

SELECT DISTINCT(`mates`)FROM(
    SELECT `time` AS `time`,`from_id` AS `mates` 
     FROM `messages` AS T WHERE (`from_id`=$uid OR `to_id`=$uid) 

    UNION

    SELECT `time` AS `time`,`to_id` AS `mates`
    FROM `messages` AS T WHERE (`from_id`=$uid OR `to_id`=$uid) 

    ) AS T 
    WHERE `mates`!='$uid'
    ORDER BY `time`

$ uid会给我一个我想要获取List的用户的变量(这里是它的A)。

1 个答案:

答案 0 :(得分:0)

无论哪个人是主要人物,您似乎都在接触主要人物和与他们交谈的人。同样不太确定当你使用DISTINCT时,MySQL会如何计算订购时间,这会删除一些记录的时间。

您可以通过以下方式获得最长时间和顺序: -

SELECT `mates`, MAX(`time`) AS LatestConv
FROM(
    SELECT `time` AS `time`,`from_id` AS `mates` 
     FROM `messages` AS T WHERE `to_id`=$uid

    UNION

    SELECT `time` AS `time`,`to_id` AS `mates`
    FROM `messages` AS T WHERE `from_id`=$uid 

    ) AS T 
GROUP BY `mates`
ORDER BY LatestConv

获取最新消息的状态: -

SELECT a.mates, a.LatestConv, IFNULL(b.Status, c.Status)
FROM
(
    SELECT mates, MAX(`time`) AS LatestConv
    FROM(
        SELECT `time` AS `time`, from_id AS mates 
        FROM messages AS T 
        WHERE to_id = $uid
        UNION
        SELECT `time` AS `time`, to_id AS mates
        FROM messages AS T 
        WHERE from_id = $uid 
        ) AS T 
    GROUP BY `mates`
) a
LEFT OUTER JOIN messages b
ON a.mates = b.from_id AND a.LatestConv = b.`time` AND b.to_id = $uid
LEFT OUTER JOIN messages c
ON a.mates = c.to_id AND a.LatestConv = c.`time` AND c.from_id = $uid
ORDER BY LatestConv

请注意,如果同一个人的多条消息共享相同的最新时间,则可能会让人感到困惑。如果可能的话,可以按如下方式处理: -

SELECT a.mates, a.LatestConv, MAX(IFNULL(b.Status, c.Status))
FROM
(
    SELECT mates, MAX(`time`) AS LatestConv
    FROM(
        SELECT `time` AS `time`, from_id AS mates 
        FROM messages AS T 
        WHERE to_id = $uid
        UNION
        SELECT `time` AS `time`, to_id AS mates
        FROM messages AS T 
        WHERE from_id = $uid 
        ) AS T 
    GROUP BY `mates`
) a
LEFT OUTER JOIN messages b
ON a.mates = b.from_id AND a.LatestConv = b.`time` AND b.to_id = $uid
LEFT OUTER JOIN messages c
ON a.mates = c.to_id AND a.LatestConv = c.`time` AND c.from_id = $uid
GROUP BY a.mates, a.LatestConv
ORDER BY LatestConv