我有一张桌子:
Visit (FromId, ToId, VisitTime)
其中FromId和ToId是FK到表
UserProfile (uid, name, age ...)
作为具有我的UID的用户,我想要选择我访问过的所有个人资料,或者在访问时间点排序的一个结果集中访问我的所有个人资料以及“访问方向”的指示。
是否可以仅使用一个MySQL查询来完成它?
答案 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;