SQL Select查询结合两个查询if / else,null,空输入

时间:2018-10-16 23:31:12

标签: sql sql-server oracle

例如,我有一张桌子

State | Zip | CategoryID | ProductID
FL    |12345|     2      |  3
GA    |98765|     1      |  5
GA    |98765|     1      |  4

我的目标是提出一个与状态,邮政编码,categoryID和productID匹配的查询。但是,我对类别2 ProductID的输入可能为null或用户输入的字符串为空,因为并不总是有与该输入相关联的productID。如果categoryID == 2,则它实际上并不关心特定的productID。但是,如果categoryID == 1,则它会关心productID。如果类别1是否等于输入或为null或空字符串,类别2检查产品ID,是否可以使用if / else?还是有办法使这两个查询合而为一?

如果类别为2,则productID的输入可以为3,但也可以为null或空字符串。因此,如果它为null,空字符串或3。我需要它返回。

FL    |12345|     2      |  3

select * from locationPurch l
where l.state = :state
and l.zip = :zip
and l.category = :category

如果类别为1,则productID的输入将始终存在。因此,如果我们要查询productID 4,它将返回。

GA    |98765|     1      |  4

select * from locationPurch l
where l.state = :state
and l.zip = :zip
and l.categoryID = :category
and l.productID = :productID

5 个答案:

答案 0 :(得分:0)

这是您想要的吗?

select l.*
from locationPurch l
where l.state = :state and
      l.zip = :zip and
      l.categoryID = :category and
      (:category <> 2 or l.productID = :productID)

答案 1 :(得分:0)

并不能100%清楚您要寻找什么条件,但是此版本假定您,如果您的categoryid = 2,那么我们不仅会获得与:productID匹配的行,而且还会匹配其中任一参数为null或表包含null。

顺便说一句,您提到的是空字符串或空字符串-我假设它们是表和参数中的整数,这意味着它们永远不会是空字符串。如果不是这样,则将is null的测试更改为isnull(l.productID,'')='' or isnull(:productID,'')=''

您对categoryid的测试也必须为categoryID='2'

select l.*
from locationPurch l
where l.state = :state and
  l.zip = :zip and
  l.categoryID = :category and
  (l.productID = :productID 
     or (:category = 2 and (l.productID is null or :productID is null))
  )

答案 2 :(得分:0)

这应该有效:

SELECT l.*
FROM locationPurch l
WHERE 
    -- we look just at categoryId 2
    (:category = 2 AND 
     l.CategoryId = 2 AND -- filter only products from Category 2 
     (
              :productId IS NULL OR -- :productId is not specified as filter
              (ISNULL(l.ProductId,-99) = :productId) OR -- :productId is specified
              (:productId IS NOT NULL AND l.ProductId IS NULL) -- :productId is specified but user hasn't inputed data for productId in table
     ) AND -- productId resolving
     (:state IS NULL OR l.state = :state) AND 
     (:zip IS NULL OR l.zip = :zip)
    ) 
    OR
    -- only category 1 is observed
    (:category = 1 AND 
     l.CategoryId = 1 AND -- filter only products from Category1 
     l.ProductId = :productId AND -- only specified productId 
     (:state IS NULL OR l.state = :state) AND -- if state is entered then use that state as filter
     (:zip IS NULL OR l.zip = :zip) -- if ZIP is entered use that zip as filter
    )

编辑:第2部分

您可以使用UNIONUNION ALL运算符加入查询,如下所示:

select * from locationPurch l
where l.state = :state
and l.zip = :zip
and l.category = :category
and l.category = 1
UNION ALL
select * from locationPurch l
where l.state = :state
and l.zip = :zip
and l.categoryID = :category
and l.productID = :productID
and l.category = 2

*这只是为了展示如何使用UNION,必须使用我在先前查询中使用的WHERE子句来进一步改进此脚本。

但是使用UNION有一些限制,请在此处阅读有关它们的信息:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/set-operators-union-transact-sql

答案 3 :(得分:0)

签出此查询:

select *
from locationPurch l
where l.state = :state
  and l.zip = :zip
  and l.categoryID = :category
  and (
    l.categoryID = 2 or l.productID = :productID
  )

如果categoryID2,则由于productID运算符,它不会关心or。如果categoryID是任何其他值(包括1),它将在productID运算符之后检查or

为此,将操作数括在 where 子句的其余部分 AND 中。

答案 4 :(得分:0)

只需尝试一下。

select * from locationPurch l
where l.state = :state
and l.zip = :zip
and l.categoryID = :category
and l.productID = case when :category = 1 then :productID else l.productID end

它将为您提供预期的输出