【问题标题】:Non-collective MySQL WHERE OR clause非集体 MySQL WHERE OR 子句
【发布时间】:2014-05-20 09:48:19
【问题描述】:

“非集体”不是正确的术语,所以请提出更好的描述,我会修改:)

基本上,我有一个查询如下:

SELECT 
  image_id, image_col1, image_col2
FROM
  images 
WHERE (
    (image_col1 = 2 AND image_col2 = 3) 
    OR
    (image_col1 = 2 AND image_col2 = 0) 
    OR
    (image_col1 = 1 AND image_col2 = 0)
  )

这将返回四行:

+----------+------------+------------+
| image_id | image_col1 | image_col2 |
+----------+------------+------------+
|         1|           2|           3|
+----------+------------+------------+
|         2|           2|           3|
+----------+------------+------------+
|         3|           2|           0|
+----------+------------+------------+
|         4|           1|           0|
+----------+------------+------------+

如果其中一个条件找到一些行,我想要它做的是忽略 WHERE 的其他部分,即在这个例子中,我只想要前两行,因为它们匹配第一个条件,如果没有匹配那个条件,我只想要第三行,因为它符合第二个条件。

目前,我正在运行 3 个查询,每个条件一个,然后使用第一个不是空结果的查询,但想尝试在一个查询中执行。

我基本上不希望它结合条件来查找与其中任何一个匹配的行,我希望它在条件返回时停止。

这可能吗?

【问题讨论】:

    标签: mysql sql where


    【解决方案1】:

    在级联中应用不同的规则并非易事。
    使用CTE 的可能性至少有助于提高可读性。

    SELECT i.image_id, i.image_col1, i.image_col2
    FROM   (SELECT image_id, image_col1, image_col2
                 , CASE WHEN (image_col1 = 2 AND image_col2 = 3) THEN 1
                        WHEN (image_col1 = 2 AND image_col2 = 0) THEN 2
                        WHEN (image_col1 = 1 AND image_col2 = 0) THEN 3 
                        ELSE 0 
                   END Cond
            FROM   images) i
           INNER JOIN (SELECT MIN(CASE 
                                    WHEN (image_col1 = 2 AND image_col2 = 3) 
                                      THEN 1
                                    WHEN (image_col1 = 2 AND image_col2 = 0) 
                                      THEN 2
                                    WHEN (image_col1 = 1 AND image_col2 = 0) 
                                      THEN 3 
                                    ELSE 0 
                                  END) Cond
                       FROM   images) a ON i.Cond = a.Cond
    

    SQLFiddle Demo

    两个子查询中的字段Cond返回哪个规则适用于该行,该规则必须是互斥的。
    第二个子查询应用相同的规则来获取适用于数据集的第一个规则,这就是为什么对规则进行编号而不是简单地检查。

    不用JOIN检查WHERE中的条件也可以做同样的事情

    SELECT image_id, image_col1, image_col2
    FROM   images
    WHERE  CASE WHEN (image_col1 = 2 AND image_col2 = 3) THEN 1
                WHEN (image_col1 = 2 AND image_col2 = 0) THEN 2
                WHEN (image_col1 = 1 AND image_col2 = 0) THEN 3 
                ELSE 0 
           END
           = 
           (SELECT MIN(CASE WHEN (image_col1 = 2 AND image_col2 = 3) THEN 1
                            WHEN (image_col1 = 2 AND image_col2 = 0) THEN 2
                            WHEN (image_col1 = 1 AND image_col2 = 0) THEN 3 
                            ELSE 0 
                       END) Cond
            FROM   images)
    

    SQLFiddle demo

    【讨论】:

      【解决方案2】:

      试试这个。

      SELECT image_id, image_col1, image_col2, 
             case when (image_col1 = 2 AND image_col2 = 3) then 1 else 0 
             case when (image_col1 = 2 AND image_col2 = 0) then 1 else 0
             case when (image_col1 = 1 AND image_col2 = 0) then 1 else 0
           END as img 
           FROM images
      

      【讨论】:

        猜你喜欢
        • 2020-11-28
        • 1970-01-01
        • 2021-02-02
        • 1970-01-01
        • 1970-01-01
        • 2018-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多