【问题标题】:check if a column contains ALL the values of another column - Mysql检查一列是否包含另一列的所有值 - Mysql
【发布时间】:2015-03-09 10:08:05
【问题描述】:

假设我有一个包含人员 ID 和其他东西 ID 的表 T1,如下所示

Table: T1
personID | stuffID 
    1    |    1
    1    |    2
    1    |    3
    1    |    4
    2    |    1
    2    |    4
    3    |    1
    3    |    2

另一个表 T2 只有一列 stuffID

Table: T2
stuffID
   1  
   2  
   3  

SELECT 得到的结果是一个与 T2 的所有 stuffID 相关联的 peopleID 表。

按照示例,结果将只有 id 1(即使它关联的所有 stuffID 都包含在 T2.stuffID 中,personID 3 也不会出现)。

【问题讨论】:

    标签: mysql sql relational-division


    【解决方案1】:

    如果我理解正确,您想从 T1 中检索所有在 T2 中找到的所有相关 stuffID 的 personID。

    您可以将其分解如下: 首先,找到与嵌套查询匹配的所有 T1 条目

    SELECT personID 
    FROM T1 WHERE stuffID IN (SELECT stuffID FROM t2)
    

    现在您需要检查该集合中的哪些条目包含您想要的所有 stuffID

    GROUP BY personID
    HAVING COUNT(DISTINCT stuffID) = (SELECT COUNT(stuffID) FROM t2)
    

    把它们放在一起:

    SELECT personID 
    FROM T1 WHERE stuffID IN (SELECT stuffID FROM t2)
    GROUP BY personID
    HAVING COUNT(DISTINCT stuffID) = (SELECT COUNT(stuffID) FROM t2)
    

    HTH。

    【讨论】:

    • 嗨,艾迪!谢谢您的回答!我试过了,它应该工作得很好(我会在几个小时内用我的数据深入检查它)。还有一个小问题:在我的例子中,T2 是我在“SELECT”之前创建的一个临时表。您的代码适用于普通表,但如果它是临时的则不能。 Sql 消息是 #1137 - 无法重新打开表:'T2'。你知道为什么吗?非常感谢
    • 嗨 Marco,除非您提供您正在使用的 SQL,否则我只能猜测问题 - 请注意,您不能在同一查询中多次引用临时表 - 请参阅 dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html
    • 非常感谢。我解决了创建临时表的两个实例。再次感谢您的友好支持。 (顺便说一句,我在网站管理区域的 phpMyAdmin 4.1.7 中使用 MySQL)
    • 您好,如果我错了,请纠正我,我对此完全陌生。这段代码:GROUP BY personID HAVING COUNT(DISTINCT stuffID) 测量每个 personID 有多少 stuffID。因此,如果一个人的 id 为 1,6,7,则结果为 3。另外,他们确实在 t2 中有一个值(在 t2 中找到了 1)。因此,尽管 1、6、7 与 1、2、3 不匹配,但他们最终会得到结果。你能告诉我我错在哪里吗,因为我的问题与被问到的问题相同,而且这段代码对我不起作用。
    • 哇,这是一个旧线程。恐怕您对该条款如何运作的理解不正确。 HAVING 子句分别匹配 t2 中的每个 stuffID,而不是将它们合并为单个值。我在这里为您做了一个示例,可以帮助您理解:sqltest.net/#912976 在此示例中,我认为您可能期望检索到人员 1 和人员 3,而代码实际上检索人员 1 和人 2(根据需要)。这是一个很好的视觉解释:w3resource.com/sql/aggregate-functions/count-having.php
    【解决方案2】:
    select personID
    from T1
    where stuffID in (select stuffID from t2)
    group by personID
    having count(distinct stuffID) = (select count(*) from t2)
    

    即选择一个人在 T2 中的 stuffid,对它们进行计数(仅区分),并验证与 t2 中相同的数字。

    【讨论】:

      【解决方案3】:
      select personID from T1 group by personID having count(distinct stuffID) in (select count(distinct stuffID) from T2)
      

      select count(distinct stuffID) from T2

      group by personID having count(distinct stuffID)

      所以两个计数应该相等才能获得所需的结果。

      【讨论】:

        【解决方案4】:

        使用count 是一种有效的方法。另外,从集合论的角度来看,你可以这样想:对于一个有效的 personID,我们不应该在 T2 中找到一个 stuffID,但在 T1 中没有连接到这个 personID。因此我们可以这样做:

        SELECT DISTINCT T1.personID
        FROM T1
        WHERE NOT EXISTS (
          SELECT T2.stuffID
          FROM T2
          WHERE T2.stuffID NOT IN (
            SELECT DISTINCT T1copy.stuffID
            FROM T1 T1copy
            WHERE T1copy.personID=T1.personID));
        

        【讨论】:

          【解决方案5】:

          试试这个

              select personID from T1
              group by personID
              having count(distinct stuffID) >= (select count(*) from t2)
          

          【讨论】:

            猜你喜欢
            • 2020-08-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-07-21
            • 1970-01-01
            • 2017-01-13
            • 1970-01-01
            相关资源
            最近更新 更多