【问题标题】:Select rows that contain more than one condition simultaneously选择同时包含多个条件的行
【发布时间】:2009-03-27 16:49:21
【问题描述】:

我有这样的表结构:

ID   cond
1    5
1    2
1    6
8    2
9    1
9    5

当我想选择包含一个或多个条件的行时,我使用 OR (...WHEN cond=2 OR cond=6 GROUP BY ID...)

但是如何选择包含多个同时按 ID 分组的条件的行? 例如。当我想查找包含条件 2 和 6 的行时,它只返回 ID 1

谢谢

【问题讨论】:

  • 如果您不想分组,为什么还要使用 group by?你能把你得到什么和你想看到什么的样本放上来吗?
  • 您能否澄清预期的输出,如上述评论者所述。

标签: mysql conditional-statements


【解决方案1】:

您可以为此使用联接:

SELECT  ID
FROM    tbl t1
        INNER JOIN
                tbl t2
                ON t1.ID = t2.ID
WHERE   t1.cond = 2
AND     t2.cond = 6

或者这个,如果 ID/cond 对是唯一的:

SELECT  ID
FROM    tbl
WHERE   cond IN (2, 6)
GROUP BY ID
HAVING COUNT(cond) = 2

【讨论】:

  • @David M:我喜欢这个,但仅适用于这种情况。对于需要包含的任何额外值,它需要另一个连接,如果您必须验证存在许多值,这可能会变得很昂贵。
  • @David M:请参阅我的一般情况解决方案。它更特定于 SQL Server,但我确信有一个 MySQL 等价物。 =)
  • 使用这种类型的 JOIN,如果将约束添加到 JOIN 子句中,有时会更明显;例如“在 t1.ID = t2.ID 和 t2.cond = 6 上的内部连接 ​​tbl t2”。更进一步“FROM tbl JOIN tbl t1 ON t1.ID = tbl.ID and t1.cond = 2”所以所有约束都很好地显示。
  • 不错的第二个选项(HAVING COUNT ...)。希望我能再次升级:)
  • @David,你总是可以使用 COUNT(DISTINCT ...)
【解决方案2】:

有多种方法可以做到这一点。

使用COUNT(最快):

SELECT id FROM tbl WHERE tbl.cond IN ( 2, 6 ) HAVING COUNT(DISTINCT cond) = 2 GROUP BY id

使用EXISTS(使用嵌套循环,在非常大的表上速度较慢,但​​比COUNT 变体更不神秘且更可扩展):

SELECT DISTINCT id FROM tbl AS tbl1 WHERE EXISTS (SELECT * FROM tbl AS tbl2 WHERE tbl1.id = tbl2.id AND tbl2.cond = 2) AND EXISTS (SELECT * FROM tbl AS tbl2 WHERE tbl1.id = tbl2.id AND tbl2.cond = 6)

使用GROUP_CONCAT(COUNT 主题的 MySql 特定变体,但如果您想要完全匹配,例如 cond=2 和 cond=6 没有其他条件,那么下面的,更改为 SELECT id, GROUP_CONCAT(DISTINCT cond ORDER BY cond) AS conds ... WHERE conds='2,6' 将执行最好)

SELECT id, ','||GROUP_CONCAT(DISTINCT cond)||',' AS conds FROM tbl WHERE INSTR(conds, ',2,') > 0 AND INSTR(conds, ',6,') > 0 GROUP BY id

【讨论】:

  • 谢谢....请问,当它是另一个条件(列)时(例如,当它是(cond=2 和 cond2=1)和(cond=6 和 cond2)时,是否可以使用第一个变体=2))?
  • 我会说,是的:SELECT id FROM tbl WHERE tbl.cond IN (2, 6) AND tbl.cond2 IN (1, 2) HAVING COUNT(DISTINCT cond) = 2 AND COUNT( DISTINCT cond2) = 2 GROUP BY id
【解决方案3】:

您可以使用子查询和组来执行此操作。假设您知道需要查找的值的数量,您可以这样做:

select
    t.ID
from
    (
        select distinct
            ID, cond
        from
            tbl
        where
            tbl.cond in (2, 6)
    ) as t
group by
    t.ID
having
    count(t.cond) = 2

对于一般情况,您只需更新必须存在的条件列表(即“(2, 6)”)以包含新值,然后更新 having 子句(即“having count(t .cond) = 2") 等于值的总数。

【讨论】:

    【解决方案4】:
    SELECT DISTINCT(ID) WHERE (cond = 2) OR (cond = 6)
    

    【讨论】:

    • OP 希望根据他们所说的,两个 cond 值都出现在 Id 的位置
    【解决方案5】:

    这是另一种语法,它对它的作用更加透明(尽管性能不高)。

    SELECT DISTINCT ID 
    FROM MyTable T
    WHERE 
      EXISTS(SELECT ID FROM MyTable T1 WHERE Cond=2 AND T1.ID=T.ID) AND
      EXISTS(SELECT ID From MyTable T2 WHERE Cond=6 AND T2.ID=T.ID)
    

    【讨论】:

      【解决方案6】:

      如果每个 id 没有重复,这可能会更灵活一些。

      SELECT id
      FROM tbl 
      GROUP BY id
      HAVING SUM(CASE cond 
          WHEN 2 THEN 1
          WHEN 6 THEN 1
          ELSE 0 END) > 1
      

      【讨论】:

        【解决方案7】:

        您是否考虑过使用 UNION 子句?

        选择 ID 从我的表 其中 cond = 2 联盟 选择编号 从我的表 其中 cond = 6

        如果您可以指定您正在寻找的确切输出,这也会有所帮助。但据我了解,UNION 将是正确的选择。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多