SQL:忽略WHERE子句中的条件

SQL:忽略WHERE子句中的条件,sql,oracle,Sql,Oracle,如果WHERE子句的计算结果为NULL,我对如何排除其中一个条件感到困惑 SELECT TB1.COL3 FROM TB1, TB2 WHERE TB1.COL1 = TB2.Col1 AND TB2.COL1 = '12345' AND (TB2.COL3 = (SELECT MIN(TB3.COL4) FROM TB3 WHERE COL1 = TB2.COL1 AND COL2 in ('A', 'B') AND COL4 IN (SELECT COL3 FROM TB4 WHERE

如果WHERE子句的计算结果为NULL,我对如何排除其中一个条件感到困惑

SELECT TB1.COL3 
FROM TB1, TB2
WHERE TB1.COL1 = TB2.Col1
AND TB2.COL1 = '12345'
AND (TB2.COL3 = (SELECT MIN(TB3.COL4)
FROM TB3
WHERE COL1 = TB2.COL1
AND COL2 in ('A', 'B') 
AND COL4 IN (SELECT COL3 FROM TB4 
WHERE COL1 = TB4.COL1))) 
AND ROWNUM = 1;
如果以下条件SELECT MIN(TB3.COL4)FROM TB3的计算结果为NULL以外的某个值,我如何修改上述查询以忽略“AND condition TB2.COL3”。如果为空,则应按如下方式执行上述查询:

SELECT TB1.COL3 
FROM TB1, TB2
WHERE TB1.COL1 = TB2.Col1
AND TB2.COL1 = '12345'
AND ROWNUM = 1;

我认为你可以通过合并来实现这一点:

SELECT TB1.COL3 
FROM TB1, TB2
WHERE TB1.COL1 = TB2.Col1
AND TB2.COL1 = '12345'
AND (TB2.COL3 = COALESCE((SELECT MIN(TB3.COL4)
FROM TB3
WHERE COL1 = TB2.COL1
AND COL2 in ('A', 'B') 
AND COL4 IN (SELECT COL3 FROM TB2 
WHERE COL1 = TB2.COL1)), TB2.COL3)) 
AND ROWNUM = 1;
这里我们只是将SELECT语句包装在
COALESCE
中,如果返回null,它将获取第二个参数的值,这与我们正在比较的列相同。由于
TB2.COL3=TB2.COL3
显然是
TRUE
,因此此筛选器不会对结果集产生任何影响

此外,通常建议您停止在FROM子句中使用逗号,并使用正确的JOIN语法。它已经存在了20多年了:

SELECT
    TB1.COL3
FROM
    TB1
    INNER JOIN TB2
        ON TB1.COL1 = TB2.Col1
WHERE
    TB2.COL1 = '12345'
    AND
    (
        TB2.COL3 = COALESCE
        (
            (
                SELECT
                    MIN(TB3.COL4)
                FROM
                    TB3
                WHERE
                    COL1 = TB2.COL1
                    AND COL2 in ('A', 'B')
                    AND COL4 IN
                    (
                        SELECT
                            COL3
                        FROM
                            TB2
                        WHERE
                            COL1 = TB2.COL1
                    )
            ),
            TB2.COL3
        )
    )
    AND ROWNUM = 1;

这个问题很令人困惑。在
中,从TB2中选择COL3,其中COL1=TB2。COL1
缺少限定符。它的计算结果为
从TB2中选择COL3,其中TB2.COL1=TB2.COL1
,因为TB2是您在子查询中使用的表。由于TB2.COL1=TB2.COL1`除了null之外始终为true,因此您将使用
从TB2中选择COL3,其中TB2.COL1不为null
。这是有意的吗?另一方面:逗号分隔的连接在1992年SQL中变得多余。请使用显式联接(
来自TB1内部联接TB2 ON…
)。然后,当查询都是大写时,很难读取。要么将关键字保留为大写,要么全部用小写。然后,由于缺少缩进,您的查询不太可读。第一个子查询在哪里开始和结束,第二个子查询在哪里?最后:你必须加入TB2吗?您没有从中选择,因此我希望
中或
存在
。使用联接可能会有获得重复结果行的风险。@ThorstenKettner为了避免混淆,我修改了SQL语句,将TB2替换为TB4。感谢您的回复和解释!我没有想过要应用COALESCE。我也同意在from子句中使用JOIN。如果TB2.COL3为NULL,这种情况并不适用于所有情况。然后条件的计算结果为False。我们如何避免这种情况?另一个
coalesce()
会起作用:
coalesce(TB2.Col3,1)=coalesce(,TB2.Col3,1)
这样它将继续运行,直到它在
COALESCES()
中同时命中
1
,并返回
TRUE
。有选择地将
或TB2.COL3为空
抛入该位可以实现此目的。50/50哪个更快。