我在这里阅读了许多加入问题,但无法理解并创建自己的问题以获得我想要的正确结果。
我现在有三个表状态,成员,好友好友表有两列friend_id和member_id
我需要更改表格结构吗?请帮助如何以我想要的方式获取记录
答案 0 :(得分:1)
对于任何合格成员的预先查询对于任何合格成员加上成员本身,然后返回加入其余表格...
select STRAIGHT_JOIN
PeopleList.Member_id,
members.last_name,
members.first_name, (etc with any other fields)
ms.status_id,
ms.description (etc with any other fields from member_status table)
from
( Select DISTINCT m.member_id
from Members m
where m.member_id = MemberDesiredVariable
union select f.friend_id AS member_id
from Friends f
where f.member_id = MemberDesiredVariable
union select f2.member_id
from Friends f2
where f2.friend_id = MemberDesiredVariable ) PeopleList
join members
on PeopleList.member_id = members.member_id
join member_status ms
on PeopleList.member_id = ms.member_id
无论在“朋友”表中是否有任何记录的人,这都应该是主要人物,例如没有条目的新人......他们至少有资格成为自己并加入成员和member_status表。
然后,在你的方案中,成员1是标准,它会查询朋友的任何“Friend_IDs”,因此DISTINCT将有1(直接来自成员)和2,其中member_id = 1,找到Friend_id = 2.现在,这个预查询有两个ID,然后继续获取你想要的其他任何细节。
第三种情况是你想要成员2 ...所以,直接查询成员表保证他们在列表中的ID要处理,但由于他们的ID不是朋友表中的“MEMBER_ID”,它必须从别人那里寻找自己的“FRIEND_ID”并抓住会员的身份证。所以现在,成员2也将找到成员1并继续获取详细信息。
对于成员3,如果你查询了Friends表,你根本就没有记录,即使成员3有一些状态记录......它必须是自己的资格以包含其余的处理......但在朋友表中不会发现自己是“member_id”或“friend_id”。
我实际上无法在我当前的位置对此进行测试,但逻辑上应该没问题。
最后,如果您希望朋友名称REGARDLESS更改“状态”,请将最后一次加入更改为member_status为LEFT JOIN。
---评论反馈
我不能特别推荐任何书籍,它只是来自多年的经验......
1.了解您的数据的关系...
2.找出最内在的“我想得到什么”
3.抛出所有其他元素,直到获得CRITERIA,而不是内容。
4.保持你的主要“获得标准”...然后加入你的其他表。
5.然后在输出结果集
尝试解决复杂查询通常会被人们试图获取的所有其他数据元素混乱。像许多其他编程任务一样...我喜欢让它工作,然后使它漂亮。查询也是如此。如果您的基线查询没有得到您想要的内容,那么您连接在一起的多少个其他表(左,外或正常连接)无关紧要,您的输出将是错误的。
我还在顶部的sql中添加了“STRAIGHT_JOIN”子句。这告诉MySql按照我指示的顺序执行查询,并且没有优化器尝试为我考虑。当连接主表(例如数百万条记录)以“查找”辅助表时,这一个子句经常出现,查询引擎错误地将查找表解释为查询表的主要查询表,从而导致性能下降......
尝试在有效的版本之间进行一些定时测试。如果它们具有相同的可比性,我通常会使用我能理解的那个,以防我将来必须修改/更改某些内容。
答案 1 :(得分:0)
-- own records
SELECT member_id, friend_id, user_name, description
FROM
(SELECT M.member_id,
M.member_id friend_id,
M.user_name,
MS.description
FROM members M
LEFT JOIN member_status MS on MS.member_id = M.member_id
UNION ALL
-- friends records
SELECT M.member_id,
F.friend_id,
MF.user_name,
MS.description
FROM members M
JOIN ( SELECT friend_id member_id, member_id friend_id from friends
UNION SELECT member_id, friend_id from friends) F
ON F.member_id = M.member_id
LEFT JOIN member_status MS on MS.member_id = F.friend_id
LEFT JOIN members MF on MF.member_id = F.friend_id) R
WHERE R.member_id = 1
答案 2 :(得分:0)
以下是使用UNION子句的解决方案。如果每个SELECT的结果很短(假设少于1000行),那么它比LEFT JOIN与OR结合更快。
如果是“彼此的朋友”,那么你的意思是:
(a)被标记为朋友的成员的身份
+
(b)被视为成员被标记为朋友的成员的地位
那么你应该使用下面的树UNION
如果只想要(a),则删除最后一个UNION。
SELECT s.status_id
FROM member_status AS s
WHERE (s.member_id=@id)
UNION ALL
SELECT s.status_id
FROM member_status AS s
INNER JOIN friends AS f ON (s.member_id=f.friend_id)
WHERE (f.member_id=@id)
UNION ALL
SELECT s.status_id
FROM member_status AS s
INNER JOIN friends AS f ON (s.member_id=f.member_id)
WHERE (f.friend_id=@id)