需要两个选择吗?

时间:2013-12-01 11:38:21

标签: mysql sql

我有一张桌子:

Visit (FromId, ToId, VisitTime)

其中FromId和ToId是FK到表

UserProfile (uid, name, age ...)

作为具有我的UID的用户,我想要选择我访问过的所有个人资料,或者在访问时间点排序的一个结果集中访问我的所有个人资料以及“访问方向”的指示。

是否可以仅使用一个MySQL查询来完成它?

3 个答案:

答案 0 :(得分:5)

SELECT  CASE WHEN a.FromID = 'yourIDHere' 
                THEN c.Name
                ELSE b.Name
        END Name,
        CASE WHEN a.FromID = 'yourIDHere' 
                THEN c.Age
                ELSE b.Age
        END Age,
        a.VisitTime,
        CASE WHEN a.FromID = 'yourIDHere' 
                THEN 'You'
                ELSE 'Friend'
        END DirectionOfVisit
FROM    Visit a
        INNER JOIN UserProfile b
            ON a.FromID = b.Uid
        INNER JOIN UserProfile c
            ON a.ToID = c.Uid
WHERE   'yourIDHere' IN (a.FromID, a.ToID)
ORDER   BY a.VisitTime

简要说明:

查询将显示您访问过的朋友或访问过您的朋友的姓名,并显示访问的方向。当它显示You时,表示您已访问过您朋友的个人资料,否则如果朋友已经访问过您,则会显示Friend

答案 1 :(得分:1)

您需要两组不同的信息(From的用户个人资料和To的用户个人资料),具体取决于访问的方向。

所以你可以:

做一个双重JOIN与很多IF的结合

  SELECT IF ( FromId = f.uid, f.name, t.name ) AS name,
       IF ( FromId = f.uid, f.age,  t.age  ) AS age,
       ...
  FROM Visit
    JOIN UserProfile AS f ON (uid = FromId)
    JOIN UserProfile AS t ON (uid = ToId)
  ORDER BY VisitTime

执行相同的操作,重命名字段,选择所有字段并在代码中进行选择,您将从元组中提取哪些字段(元组现在是双倍大小)

SELECT f.name as f_name, t.name AS t_name, ...

使用UNION。这是两个查询汇总在一起,然后你需要一个排序

SELECT * FROM (
    SELECT UserProfile.*, 'From' AS direction
        FROM UserProfile JOIN Visit ON (FromId = uid)
    UNION
    SELECT UserProfile.*, 'To' AS direction
        FROM UserProfile JOIN Visit ON (ToId = uid)
) AS visits ORDER BY VisitTime

我认为第三种选择可能更简单。第一种可以产生更好的性能,取决于索引和实际的表结构和大小。对于数百或数千次访问的表格,差异可能微不足道。

答案 2 :(得分:0)

您可以使用WHERE扩展OR子句以包含第二个条件:

SELECT * FROM Visit WHERE FromId = uid OR ToId = uid;

这将为您提供所有访问权限,但如果您需要所有用户配置文件,只需扩展SELECT语句:

SELECT * FROM UserProfile, Visit WHERE FromId = uid OR ToId = uid;

要对结果进行排序,只需在结尾添加ORDER BY

SELECT * FROM UserProfile, Visit WHERE FromId = uid OR ToId = uid SORT BY VisitTime DESC;