简体   繁体   English

SQL - WHERE中的CASE表达式

[英]SQL - CASE expression inside WHERE

I read about using the CASE expression inside the WHERE clause here: 我在这里阅读了有关在WHERE子句中使用CASE表达式的内容:

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

I'm trying to use this to filter results from my select statement, based on a contract number which will be passed in by the user's application. 我正在尝试使用它来根据用户应用程序传递的合同号来过滤select语句的结果。 My code currently throws an error of 'Invalid parameter' no matter what is passed in. I verified SELECT/FROM are working fine, as where as a WHERE clause without a CASE expression. 我的代码当前抛出了'无效参数'的错误,无论传入什么。我验证SELECT / FROM工作正常,如没有CASE表达式的WHERE子句。 Here is my code. 这是我的代码。

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

The redundancy of the code is for troubleshooting purposes, I'm planning on using wildcard filtering on the CASE later. 代码的冗余用于故障排除,我打算稍后在CASE上使用通配符过滤。 I'm focusing on getting the syntax down right now. 我正专注于立即降低语法。 I believe this should return all records for which the parameter matches the contract number stored in the table. 我相信这应该返回参数与表中存储的合同号匹配的所有记录。 Any help or advice would be greatly appreciated. 任何帮助或建议将不胜感激。

Are you sure you want to do this? 你确定你要这么做吗? Your case statement ALWAYS returns @ContractNo . 你的case语句总是返回@ContractNo I think what you are looking for is this: 我认为你在寻找的是:

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

The filter above says "give me the contract where the ContractNo equals the parameter, or all of them if the parameter is 0. 上面的过滤器说“给我合同,其中ContractNo等于参数,或者如果参数为0,则给出所有ContractNo

The previous filter only filtered where the contract number field is exactly equal to the parameter. 仅过滤合同编号字段与参数完全相等的前一过滤器。

Regardless, you should do this instead: 无论如何,你应该这样做:

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

The logic is much easier to understand, and on top of that (don't quote me on this), the optimizer probably will work better outside of the case statement. 逻辑更容易理解,除此之外(不要引用我),优化器可能会在case语句之外更好地工作。

After reading your explanation, there's a better way to do this without CASE : 阅读完解释后,有一种更好的方法可以在没有CASE下执行此操作:

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

This will return only matching contract numbers, unless @ContractNo is 0, in which case it will return all records. 这将仅返回匹配的合同号,除非@ContractNo为0,在这种情况下,它将返回所有记录。

Edit: I've just noticed that casperOne proposed the same thing . 编辑:我刚刚注意到casperOne提出了同样的事情 I didn't see that. 我没有看到。 Big up yourself. 大自己。

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

Maybe you forgot to declare @ContractNo? 也许你忘了宣布@ContractNo? Is it comparable to 0 and to tblContracts.ContractNo? 它是否与0和tblContracts.ContractNo相当?

Move your close parenthesis to before the = like so: 将你的右括号移到=之前,如下所示:

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

I fail to see what this case statement will do though... you're returning the same thing in the event the @ContractNo = 0 or if it's not... 我没有看到这个案例陈述会做什么但是...如果@ContractNo = 0或者它不是......你会返回相同的东西......

The correct syntax is: 正确的语法是:

  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>

Regardless of the syntax though, your example doesn't make a lot of sense, if you're looking for all items that match or have a Contract Number of 0, then you would do: 不管语法如何,你的例子没有多大意义,如果你正在寻找匹配或者合同号为0的所有项目,那么你会这样做:

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

Which seems to make far more sense than what you're attempting to use the case statement for. 这似乎比你试图使用case语句更有意义。

Edit: I must've misread the question slightly - the missing param usually means that the parameter (in this case @ContractNo) is not declared in the scope of your query/procedure. 编辑:我一定是误解了这个问题 - 缺少的参数通常意味着参数(在本例中为@ContractNo)未在查询/过程的范围内声明。 But someone already pointed that out, so I can't take any credit for that. 但是有人已经指出了这一点,所以我不能相信这一点。

The reason for the case statement, including the whole "If it's 0, give the parameter, and otherwise, just give the parameter" was to test it to try to get the syntax right. case语句的原因,包括整个“If it为0,给出参数,否则,只给出参数”是为了测试它以试图使语法正确。 Originally, I had tried saying "If it's 0, then pass in '%', to return every value. The code I posted in there was because I kept getting 'Invalid Parameter' and figured there must be something wrong with my syntax. When I separated it into basic parameter matching like so, 最初,我试过说“如果它是0,然后传入'%',返回每个值。我在那里发布的代码是因为我一直得到'无效参数'并且认为我的语法一定有问题。我把它分成基本的参数匹配,像这样,

WHERE @ContractNo = tblContracts.ContractNo

it returned records fine. 它返回记录很好。 Let me explain a bit more. 让我解释一下。

I'm pulling from a bunch of different tables, and filtering the content with information not included in the select statement (ie tblContracts is not having information pulled from it by Select, it's only used in Where). 我从一堆不同的表中提取,并使用select语句中未包含的信息过滤内容(即tblContracts没有通过Select从中提取信息,它仅在Where中使用)。 The user will select from a combo box which will have the different contract numbers, as well as a default value of 'All'. 用户将从具有不同合同号的组合框中进行选择,以及默认值“全部”。

I'm going to have an event for when the index of the combo box changes. 当组合框的索引发生变化时,我将发生一个事件。 If it's 'All', 0 will be passed in as a parameter and I want no filtering done. 如果它是'All',0将作为参数传入,我不想进行过滤。 Otherwise, I just want the information for that contract number (the reason for Else @ContractNo). 否则,我只想要该合同号的信息(Else @ContractNo的原因)。

Recursive's post solved my issue precisely. Recursive的帖子正好解决了我的问题。

I saw complaints about the clarity of my original post. 我看到有关我原帖的清晰度的投诉。 In the future, what can I do to make what I'm saying more straight forward? 在未来,我能做些什么才能让我说的更直接? I'm not used to phrasing questions about code, and apologize for any muddled things it had. 我不习惯于对代码的问题进行措辞,并为任何混乱的事情道歉。 Did I just need to provide the extended details like in my 2nd post? 我是否只需要在第二篇文章中提供扩展的详细信息?

Thanks again for all the help. 再次感谢所有的帮助。

Don't you mean something like this? 你的意思不是这样吗?

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

Where @ContractNo is variable of the same datatype as tblContracts.ContractNo 其中@ContractNo是与tblContracts.ContractNo相同的数据类型的变量

Why do you even need a case statement? 为什么你甚至需要一个案例陈述?

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

This makes no sense since you could simply write this as 这没有任何意义,因为你可以简单地写这个

Where @contractNo = tblContracts.contractNo 其中@contractNo = tblContracts.contractNo

Is the contract number actually a numeric or is it a string that always happens to be a numeric. 合同号实际上是数字还是字符串总是恰好是数字。 Check your data types between the table and the parameter and the CASE statement (for example, "= 0" or "= '0'") 检查表与参数和CASE语句之间的数据类型(例如,“= 0”或“='0'”)

This syntax should work (it does in Oracle) 这个语法应该有效(在Oracle中)

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

when you say: 当你说:

I'm pulling from a bunch of different tables, and filtering the content with information not included in the select statement (ie tblContracts is not having information pulled from it by Select, it's only used in Where). 我从一堆不同的表中提取,并使用select语句中未包含的信息过滤内容(即tblContracts没有通过Select从中提取信息,它仅在Where中使用)。 The user will select from a combo box which will have the different contract numbers, as well as a default value of 'All'. 用户将从具有不同合同号的组合框中进行选择,以及默认值“全部”。

Then it sounds to me that should have an "Where exists" clause. 然后听起来应该有一个“Where exists”条款。 since your not pulling any info out of that table?! 既然你没有从那张桌子中取出任何信息?!

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

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