【问题标题】:How to filter users with a joined table where the values for the 'blocked' field will be either 1, 0, or NULL如何使用“blocked”字段的值为 1、0 或 NULL 的连接表过滤用户
【发布时间】:2011-03-17 21:13:16
【问题描述】:

我目前有两张桌子:

用户

身份证

等等……

连接

user_id_1

user_id_2

被屏蔽

*其中user_id_1是关注用户,user_id_2是关注用户(在推特模型中)*


我目前正在修改我的内部消息传递系统,以允许所有用户向所有其他用户发送消息,唯一的限制是如果用户 A 向用户 B 发送消息,但用户 B 阻止了用户 A,则消息将无法通过。

考虑到这一点,看看这个查询:

SELECT u.id, IFNULL(c.blocked, 0) AS blocked
FROM cms_users u
    LEFT JOIN cms_connections c ON u.id=c.user_id_2 AND c.user_id_1=71
WHERE u.id IN (62, 65, 89, 90)

这里的想法是用户 71 试图向用户 62、65、89 和 90 发送消息。用户 71 正在关注 62、65 和 89,但没有关注 90。但是,用户 89 已阻止用户 71。这意味着连接表上有如下所示的条目:

user_id_1       user_id_2       blocked
71              62              0
71              65              0
71              89              1

当我运行这个查询时,我得到这个结果:

user_id_1       blocked
62              0
65              0
89              1
90              0

这正是我所期望的,但是如果我将 WHERE 子句更改为如下所示:

WHERE u.id IN (62, 65, 89, 90) AND blocked=0

然后我明白了:

user_id_1       blocked
62              0
65              0

这让我感到困惑,因为我期待三行:上面的两行和用户 90 的一行。我还尝试使用 HAVING blocked!=1HAVING blocked=0 执行 GROUP BY,它们都产生同样的结果。我还尝试将创建的列的名称更改为 blockherpderp 只是为了检查是否与我的 JOIN 发生冲突,但这产生了相同的结果。

很想看看你们能想出什么:-)

【问题讨论】:

    标签: mysql join left-join


    【解决方案1】:

    更改为IFNULL(c.blocked, 0)

    SELECT u.id, 
           Ifnull(c.blocked, 0) AS blocked 
    FROM   cms_users u 
           LEFT JOIN cms_connections c 
             ON u.id = c.user_id_2 
                AND c.user_id_1 = 71 
    WHERE  u.id IN ( 62, 65, 89, 90 ) 
           AND Ifnull(c.blocked, 0) = 0 
    

    如果改写成这个查询可以改进

    SELECT u.id, 
           Ifnull(c.blocked, 0) AS blocked 
    FROM   cms_users u 
           LEFT JOIN cms_connections c 
             ON c.user_id_1 = 71  
                AND u.id = c.user_id_2 
           JOIN (SELECT 62 AS uu 
                 UNION ALL 
                 SELECT 65 AS uu 
                 UNION ALL 
                 SELECT 89 AS uu 
                 UNION ALL 
                 SELECT 90 AS uu) d 
             ON u.id = d.uu 
    WHERE  Ifnull(c.blocked, 0) = 0 
    

    你需要索引

    • (cms_users.id)
    • (cms_connections.user_id_1,cms_connections.user_id_2,cms_connections.user_id_2.blocked)

    【讨论】:

      【解决方案2】:

      尝试:HAVING IFNULL(c.blocked,0) = 0

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 1970-01-01
        • 1970-01-01
        • 2021-07-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多