我可以在WHERE子句中使用IF语句来确定哪些AND将成为查询的一部分吗?

时间:2018-02-08 20:34:45

标签: sql if-statement where

我有一个SQL语句,在WHERE cluse中有几个AND,我想知道我是否可以在WHERE子句下有一个IF THEN ELSE语句来确定将执行什么AND。

将向此查询传递三个参数

WHERE  tlv.active = 1
AND tli.active = 1
AND t.endWorkShiftId IS NOT NULL
AND t.voidTypeId IS NULL
AND tlv.customerId = 1
AND tlv.locationId = 1
AND tlv.dockId = 3

IF ( :referenceId IS NULL ) {
    AND tlv.vendorCldcId = :vendCldId
    AND tlv.vendorId = :vendId
}
ELSE {
    AND vru.refId = :referenceId
}

2 个答案:

答案 0 :(得分:1)

不,没有IF。 CASE也不适用。但是你可以使用更复杂的布尔表达式:

WHERE  tlv.active = 1
AND tli.active = 1
AND t.endWorkShiftId IS NOT NULL
AND t.voidTypeId IS NULL
AND tlv.customerId = 1
AND tlv.locationId = 1
AND tlv.dockId = 3
AND (
    (
        :referenceId IS NULL
        AND tlv.vendorCldcId = :vendCldId
        AND tlv.vendorId = :vendId
    ) OR (
        :referenceId IS NOT NULL
        AND vru.refId = :referenceId
    )
)

<强>更新

顺便说一下:这种查询是一种性能反模式。复杂表达式阻止了大多数数据库系统中的高效表连接。

除此之外,您应该创建两个单独的,更简单的查询:一个用于referenceId IS NULL,另一个用于referenceId IS NOT NULL,并且可以调用其中一个。

答案 1 :(得分:1)

不,因为IF是命令式语言构造,而SQL查询是根据逻辑谓词定义的(例如,它可以自动优化查询执行计划)。所以你可以达到同样的效果,你只需要在功能上思考&#34; (如在函数式语言中,如Haskell) - 增加了确保查询is still Sargable的难度。

在你的情况下,你可能想要这个:

...
AND
tlv.dockId = 3
AND
(
    (
        :referenceId IS NULL
        AND
        tlv.vendorCldcId = :vendCldId
        AND
        tlv.vendorId = :vendId
    )
    OR
    (
        :referenceId IS NOT NULL
        AND
        vru.refId = :referenceId
    )
)

请注意,根据DBMS,这可能有一个次优的执行计划,因为查询引擎在依赖OR时可能无法优化 - 替代:referenceId条件,尤其是在MSSQL Server的情况下:

......一般建议似乎是为每个可能的参数集编写单独的查询。