【问题标题】:complex join query in mysqlmysql中的复杂连接查询
【发布时间】:2012-11-29 02:22:51
【问题描述】:

大家好,

我真的需要你的帮助。我必须获取所有用户的列表(不同): - 在比赛中进行实时签到( checkins.ctype = 'live' ) - 他们最喜欢的球队(见 fanusers_teams ) - 以 3 个或更多的目标差获胜。

最喜欢的球队,可能是 info_matches.team_id1 或 info_matches.team_id2 或两者兼而有之。

以下是相关表格的小设计:

我尝试过的方法有效率为 80%(所以它不会 :( )因为它返回了一些正确的用户(他们最喜欢的团队有 3+ 个目标差异),但也返回了没有最喜欢的用户. 球队在这种情况下。我认为他们被退回是因为他们为一场比赛进行了现场签到,其中一支球队或另一支球队以 3 球以上的差距获胜。

这是我的查询:

选择不同的 f.id 从 粉丝f 左连接 签入 c ON f.id = c.fanuser_id 左连接 info_matches m ON m.id = c.match_id 在哪里 c.ctype = 'live' 和 ( m.team_id1 IN( 选择不同的 m1.team_id1 从 info_matches m1 正确加入 fanusers_teams ft ON m1.team_id1 = ft.team_id 正确加入 fanusers f ON f.id = ft.fanuser_id 在哪里 m1.pointsteam1 - m1.pointsteam2 >= 3 ) 要么 m.team_id2 IN( 选择不同的 m2.team_id2 从 info_matches m2 正确加入 fanusers_teams ft ON m2.team_id2 = ft.team_id 正确加入 fanusers f ON f.id = ft.fanuser_id 在哪里 m2.pointsteam2 - m2.pointsteam1 >= 3 ) )

如果有人成功解决了这个问题,我也很感激我做错了什么。

谢谢。

【问题讨论】:

  • 让我印象深刻的是,您正在从粉丝到签到的 LEFT 加入;您绝对不希望这样,因为您想要已签入游戏的用户。我将从您的分析开始,看看是否有任何其他 OUTER 联接应该是 INNER。

标签: mysql join


【解决方案1】:

我也找到了解决查询的方法,但不如 Tom 做的那么好。

我的方式:

选择不同的 f.id AS user_id 从 粉丝f 左连接 签入 c ON f.id = c.fanuser_id 左连接 info_matches m ON m.id = c.match_id 在哪里 c.ctype = '直播' 和 m.matchisfinished = 1 和 c.fanuser_id 不在(SELECT DISTINCT f1.id 从 粉丝f1 左连接 fanusers_stickers fs 开 f1.id = fs.fanuser_id 在哪里 fs.sticker_id = 35 ) 和 ( ( m.team_id1 IN ( SELECT DISTINCT ft.team_id 从 fanusers_teams 英尺 内部联接 签到 c1 在 ft.fanuser_id = c1.fanuser_id 在哪里 f.id = c1.fanuser_id ) 和 m.pointsteam1-m.pointsteam2>=3 ) 要么 ( m.team_id2 IN(选择不同的 ft.team_id 从 fanusers_teams 英尺 内部联接 签到 c1 在 ft.fanuser_id = c1.fanuser_id 在哪里 f.id = c1.fanuser_id ) 和 m.pointsteam2-m.pointsteam1>=3 ) )

所以目前,即使我很高兴自己解决了查询,我也会使用汤姆的查询:)。

【讨论】:

    【解决方案2】:

    这样的事情应该可以工作:

    SELECT  DISTINCT f.id 
    
    FROM    fanusers f 
    
            JOIN checkins c 
            ON f.id = c.fanuser_id 
    
            JOIN fanusers_teams ft
            ON f.id = ft.fanuser_id
    
            JOIN info_matches m 
            ON m.id = c.match_id 
            AND 
            (
                (ft.team_id = m.team_id1 AND pointsteam1 - pointsteam2 >= 3) 
            OR 
                (ft.team_id = m.team_id2 AND pointsteam2 - pointsteam1 >= 3)
            )
    
    WHERE   c.ctype = 'live'
    

    【讨论】:

    • 非常优雅,无需解释。谢谢。
    • 没问题。我试图尽可能地简化它。最简单的解决方案通常是最好的解决方案。
    猜你喜欢
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2010-11-02
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多