【问题标题】:Join and multiple and conditions加入和多重和条件
【发布时间】:2014-09-23 21:16:35
【问题描述】:

我有用户表

ID     NAME
1      John
2      Mike
3      Jack

以及带有属性和用户 ID 的表格

USER   ATTRIBUTE
1      1
1      2
2      4

我需要选择属性为 1 和 2 的所有用户(因此,在此示例中,用户 #1 John)。属性可以多于两个。

我试过了

SELECT * FROM user u LEFT JOIN attributes a ON u.id = a.user 
WHERE a.attribute = 1 AND a.attribute = 2

但当然它不起作用..

【问题讨论】:

    标签: mysql sql symfony1 doctrine-1.2


    【解决方案1】:

    您需要结合使用IN() 和GROUP BY ... HAVING 来实现此目的。如果您只需要用户 ID,也无需加入。所以像:

    SELECT user, COUNT(attribute) AS attribute_count
    FROM attributes
    WHERE attribute IN(...) /* include your set of attributes here */
    GROUP BY user
    HAVING attribute_count = ? /* include number equal to number of attribute ID's in IN() above */
    

    如果您需要用户 ID 和名称,您可以简单地将源自上述查询的记录集作为过滤器加入到用户表中:

    SELECT user.id, user.name
    FROM user
    INNER JOIN
      (
        SELECT user, COUNT(attribute) AS attribute_count
        FROM attributes
        WHERE attribute IN(...) /* include your set of attributes here */
        GROUP BY user
        HAVING attribute_count = ? /* include number equal to number of attribute ID's in IN() above */
      ) AS filter
      ON user.id = filter.user
    

    【讨论】:

    • 这是大查询,用户表是“核心”。如果我已经在其他地方使用过having 怎么办? (显示距离选定区域 X 公里内的用户)
    • @poh 实际上,当您输入评论时,我正在展示如何通过连接将该过滤器应用于主表。
    【解决方案2】:

    have 子句可以和 sum 一起使用

    SELECT u.id FROM user u 
    INNER JOIN attributes a ON u.id = a.user 
    group by u.id
    having ( sum(case when attribute in (1,2) then 1 else 0 end) ) =2
    

    【讨论】:

      【解决方案3】:

      您正在寻找 EXIST 属性 1 和 2 的所有用户。解决此问题的一种方法(顾名思义)是 EXISTS 子句:

      select * 
      from users u
      where exists
      (
        select *
        from user_attributes ua
        where ua.user = u.id
        and ua.attribute = 1
      )
      and exists
      (
        select *
        from user_attributes ua
        where ua.user = u.id
        and ua.attribute = 2
      );
      

      另一种方法是:查找所有同时具有这两个属性的用户 id,然后从 users 表中选择。

      select *
      from users
      where id in
      (
        select user
        from user_attributes
        where attribute in (1,2)
        group by user
        having count(*) = 2 
      );
      

      如果属性中有重复条目,则必须将 count(*) 替换为 count(distinct attribute)。

      还有其他方法可以解决这个问题。我认为这两个提到的是相当直截了当的。

      【讨论】:

        【解决方案4】:

        你需要一个小组……拥有

        SELECT u.name
        FROM
            users u
        JOIN
            attributes a
            ON u.id = a.user
        WHERE a.id IN (1,2)
        GROUP BY u.name
            HAVING COUNT(*) = 2
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-14
          • 2011-01-10
          • 2019-11-29
          • 1970-01-01
          • 1970-01-01
          • 2010-11-30
          • 2013-07-22
          • 1970-01-01
          相关资源
          最近更新 更多