非集体MySQL WHERE OR子句

时间:2014-05-20 09:48:19

标签: mysql sql where

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

基本上,我的查询如下:

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个查询,每个条件对应一个条件,然后使用第一个不是空结果的查询,但是想要尝试在一个查询中执行。

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

这可能吗?

2 个答案:

答案 0 :(得分:2)

在级联中使用不同的规则并不是一件容易的事 使用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

答案 1 :(得分:0)

试试这个。

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