2011-04-06 91 views
1

我在这里读了很多加入问题,但无法理解并创建我自己的以获得我想要的正确结果。加入在哪里条件

我有三个表,现在是状态成员朋友朋友表有两列friend_id和member_id

  1. 所有三个表都member_id会员表的常见主ID
  2. 现在我想获得所有成员和会员的朋友创建的状态
  3. 如果我有三个成员与ID的1,2,3
  4. 朋友表有ID的1,2所以这两个成为朋友相互
  5. 2有5次状态更新和1个有2个状态和3在状态表
  6. 1次更新,如果我对查询部件2,它应该返回7记录...(5 2和2为1)和,如果我查询针对构件1则它应该返回相同的记录作为点5

做我不应该返回构件3.

  • 的记录需要改变我的表格结构?请大家帮忙如何获得创纪录的,我想

    three tables structure attached

  • +0

    当你说“friends table have id's 1,2”是两行,或只有一行member_id = 1和friend_id = 2? – Skrol29 2011-04-06 10:27:16

    +0

    @ Skrol29只有一行,其中member_id = 1,friend_id = 2 – Yasir 2011-04-06 11:06:07

    回答

    1

    如何预先查询到的朋友表,任何符合条件的成员PLUS成员本身,然后回加盟的休息方式表...

    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并继续获取你想要的其他细节。

    THIRD方案是你想要成员2 ...所以,直接查询成员表保证他们在列表中的ID进行处理,但由于他们的ID不是作为朋友表中的“MEMBER_ID”,它有从其他人那里查找自己的“FRIEND_ID”,并抓取该会员的ID。所以现在,会员2也会找到会员1并继续获取详细信息。

    对于会员3,如果您对Friends桌面进行查询,则根本不会收到任何记录,即使成员3有一些状态记录也是如此......它必须有资格对自己进行包容用于处理...但是不会在朋友表中找到自己作为“member_id”和“friend_id”。

    我实际上无法在我目前的位置进行测试,但逻辑上应该没有问题。

    最后,如果你想让朋友名称REGARDLESS具有任何“状态”更改,请将最后一次加入member_status更改为LEFT JOIN。

    ---评论反馈

    我不能具体建议任何书籍,它只是来自于多年的经验... 1.了解你的数据关系...
    2.找出最内层的“我想要得到什么”。
    3.抛出所有其他元素,直到获得标准,而不是内容。 4.保持您的主要“前提条件”......然后加入您的其他表格。 5.然后在输出结果集中添加所需的所有其他字段

    尝试解决复杂查询通常可能会被所有其他人尝试获取的数据元素混淆。像许多其他编程任务一样......我喜欢让它工作,然后让它变得漂亮。查询也是如此。如果你的基线查询没有得到你想要的东西,那么你连接在一起的多少个表格(左边,外部或正常连接)并不重要,你的输出将会是错误的。

    我还在顶部的sql中添加了“STRAIGHT_JOIN”子句。这告诉MySql按照我指示的顺序执行查询,并且没有优化器试图为我思考。在加入主表(例如数百万条记录)以“查找”次表时,这一个子句频繁出现,查询引擎已错误地将查询表解释为查询哪些性能被杀死的主查询表...

    尝试在工作版本之间进行一些定时测试。如果他们具有同等的可比性,那么我通常会选择我能理解的情况,以防我将来需要修改/更改某些内容。

    +0

    非常感谢你DRapp它的工作原理非常好:)你没有测试就写出来呵呵你能否推荐任何书或者关于sql的教程,我可以提高我的sql技能...... Manji查询也有效不知道哪一个更好,但你的查询看起来更干净... – Yasir 2011-04-06 20:40:23

    +0

    没问题,我更新了其他查询澄清/调整的答案。 – DRapp 2011-04-07 00:25:43

    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 
    
    +0

    Manji非常感谢您的支持,只需添加或语句很少....加入friends.member_id = members.member_id或friends.friend_id = members。 member_id ...你能描述整个查询吗?详细信息:) – Yasir 2011-04-06 11:16:02

    +1

    如果成员没有朋友,那么即使成员具有状态,此查询也不会返回任何记录。 – Skrol29 2011-04-06 11:35:29

    +0

    嗨Manji ....有1个问题查询返回成员id 1,2相同的第一和第二名称,但返回成员1和2的记录它没关系在哪里作出改变,所以它返回不同的第一,第二个名称? – Yasir 2011-04-06 11:42:41

    0

    这里是使用UNION子句的解决方案。如果每个SELECT的结果都很短(假设少于1000行),那么它比使用OR的LEFT JOIN更快。

    如果“对方的朋友”你的意思是你想要的:
       (一)成员的状态标记为朋友
        +
       (b)该成员的地位其中认为的成员标记为朋友
    那么你应该使用下面的树UNION。
    如果你只想要(a),然后删除最后一个UNION。

    SELECT s.status_id 
    FROM member_status AS s 
    WHERE ([email protected]) 
    
    UNION ALL 
    
    SELECT s.status_id 
    FROM member_status AS s 
    INNER JOIN friends AS f ON (s.member_id=f.friend_id) 
    WHERE ([email protected]) 
    
    UNION ALL 
    
    SELECT s.status_id 
    FROM member_status AS s 
    INNER JOIN friends AS f ON (s.member_id=f.member_id) 
    WHERE ([email protected])