繁体   English   中英

SQL - WHERE中的CASE表达式

[英]SQL - CASE expression inside WHERE

我在这里阅读了有关在WHERE子句中使用CASE表达式的内容:

http://scottelkin.com/sql/using-a-case-statement-in-a-sql-where-clause/

我正在尝试使用它来根据用户应用程序传递的合同号来过滤select语句的结果。 我的代码当前抛出了'无效参数'的错误,无论传入什么。我验证SELECT / FROM工作正常,如没有CASE表达式的WHERE子句。 这是我的代码。

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)

代码的冗余用于故障排除,我打算稍后在CASE上使用通配符过滤。 我正专注于立即降低语法。 我相信这应该返回参数与表中存储的合同号匹配的所有记录。 任何帮助或建议将不胜感激。

你确定你要这么做吗? 你的case语句总是返回@ContractNo 我认为你在寻找的是:

where 
    case @ContractNo 
        when 0 then tblContracts.ContractNo 
        else @ContractNo 
    end = tblContracts.ContractNo

上面的过滤器说“给我合同,其中ContractNo等于参数,或者如果参数为0,则给出所有ContractNo

仅过滤合同编号字段与参数完全相等的前一过滤器。

无论如何,你应该这样做:

where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo

逻辑更容易理解,除此之外(不要引用我),优化器可能会在case语句之外更好地工作。

阅读完解释后,有一种更好的方法可以在没有CASE下执行此操作:

WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo

这将仅返回匹配的合同号,除非@ContractNo为0,在这种情况下,它将返回所有记录。

编辑:我刚刚注意到casperOne提出了同样的事情 我没有看到。 大自己。

试着省略错误位置的括号 - 正确的一个应该在“结束”之后。

也许你忘了宣布@ContractNo? 它是否与0和tblContracts.ContractNo相当?

将你的右括号移到=之前,如下所示:

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END)=tblContracts.ContractNo

我没有看到这个案例陈述会做什么但是...如果@ContractNo = 0或者它不是......你会返回相同的东西......

正确的语法是:

  Select...
  ...
  Where(
    Case
      When <Condition>
        Then <Return if true>
        Else <Return if false>
      End
 ) = <Whatever is being matched to the output of the case statement>

不管语法如何,你的例子没有多大意义,如果你正在寻找匹配或者合同号为0的所有项目,那么你会这样做:

Select...
...
Where (
  @ContractNo = 0 Or
  @ContractNo = tblContracts.ContractNo
)

这似乎比你试图使用case语句更有意义。

编辑:我一定是误解了这个问题 - 缺少的参数通常意味着参数(在本例中为@ContractNo)未在查询/过程的范围内声明。 但是有人已经指出了这一点,所以我不能相信这一点。

case语句的原因,包括整个“If it为0,给出参数,否则,只给出参数”是为了测试它以试图使语法正确。 最初,我试过说“如果它是0,然后传入'%',返回每个值。我在那里发布的代码是因为我一直得到'无效参数'并且认为我的语法一定有问题。我把它分成基本的参数匹配,像这样,

WHERE @ContractNo = tblContracts.ContractNo

它返回记录很好。 让我解释一下。

我从一堆不同的表中提取,并使用select语句中未包含的信息过滤内容(即tblContracts没有通过Select从中提取信息,它仅在Where中使用)。 用户将从具有不同合同号的组合框中进行选择,以及默认值“全部”。

当组合框的索引发生变化时,我将发生一个事件。 如果它是'All',0将作为参数传入,我不想进行过滤。 否则,我只想要该合同号的信息(Else @ContractNo的原因)。

Recursive的帖子正好解决了我的问题。

我看到有关我原帖的清晰度的投诉。 在未来,我能做些什么才能让我说的更直接? 我不习惯于对代码的问题进行措辞,并为任何混乱的事情道歉。 我是否只需要在第二篇文章中提供扩展的详细信息?

再次感谢所有的帮助。

你的意思不是这样吗?

SELECT * 
    FROM tblContracts
    WHERE     
    CASE 
       WHEN tblContracts.ContractNo = 0 THEN @ContractNo 
       ELSE tblContracts.ContractNo
    END = tblContracts.ContractNo

其中@ContractNo是与tblContracts.ContractNo相同的数据类型的变量

为什么你甚至需要一个案例陈述?

当@ContractNo = 0然后(0 = tblContracts.ContractNo)否则@ContractNo然后(@ContractNo = tblContracts.ContractNo)

这没有任何意义,因为你可以简单地写这个

其中@contractNo = tblContracts.contractNo

合同号实际上是数字还是字符串总是恰好是数字。 检查表与参数和CASE语句之间的数据类型(例如,“= 0”或“='0'”)

这个语法应该有效(在Oracle中)

WHERE CASE WHEN tblContracts.ContractNo = 0 
           THEN @ContractNo 
           ELSE tblContracts.ContractNo
      END = tblContracts.ContractNo

当你说:

我从一堆不同的表中提取,并使用select语句中未包含的信息过滤内容(即tblContracts没有通过Select从中提取信息,它仅在Where中使用)。 用户将从具有不同合同号的组合框中进行选择,以及默认值“全部”。

然后听起来应该有一个“Where exists”条款。 既然你没有从那张桌子中取出任何信息?!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM