简体   繁体   English

有没有办法在sql的where子句中使用in或=与case语句一起使用?

[英]Is there a way to use in or = with a case statement in the where clause in sql?

I have a stored procedure that may or may not get a string list of int ids.我有一个存储过程,它可能会或可能不会获得 int id 的字符串列表。 When it doesn't get it the value is: ' '.当它没有得到它的价值是:' '。 Other wise its something like this: '500,507,908'其他明智的事情是这样的:'500,507,908'

I'm trying to use it like this:我正在尝试像这样使用它:

select ID as projectTeamId, Employee_ID, Supervisor_ID 
from ProjectTeam 
where Project_ID = @projectId and IsDeleted = 0 and 
        ID in (CASE @stringList WHEN '' THEN ID ELSE (SELECT * from TurnListStringIntoTable(@stringList)) END)

to get a result set but it errors out with this code when the string list comes in blank:获取结果集,但当字符串列表为空白时,此代码出错:

An error has occurred while processing Report 'MassReleaseHoursReport': Subquery returned more than 1 value.处理报告“MassReleaseHoursReport”时发生错误:子查询返回了 1 个以上的值。 This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.当子查询跟随 =、!=、<、<=、>、>= 或当子查询用作表达式时,这是不允许的。

I know its an issue where id needs to = id instead of being in id.我知道这是一个问题,其中 id 需要 = id 而不是在 id 中。 Any ideas on how I can have the case statement work with @stringList = '' then id = id else id in (SELECT * from TurnListStringIntoTable(@stringList))?关于如何让 case 语句与 @stringList = '' then id = id else id in (SELECT * from TurnListStringIntoTable(@stringList)) 一起工作的任何想法?

TurnListStringIntoTable returns a table from a string list which in my case is just the project Team ID TurnListStringIntoTable 从字符串列表中返回一个表,在我的例子中它只是项目团队 ID

I would recommend boolean logic rather than a case expression:我会推荐布尔逻辑而不是case表达式:

where 
    Project_ID = @projectId 
    and IsDeleted = 0 
    and (
        @stringList = ''
        or id in (select * from TurnListStringIntoTable(@stringList))
    )

Unrelated side note: if you are running SQL Server, as I suspect, and your version is 2016 or higher, you can use built-in function string_split() instead of your customer splitter.无关的旁注:如果您正在运行 SQL Server,正如我怀疑的那样,并且您的版本是 2016 或更高版本,您可以使用内置函数string_split()而不是您的客户拆分器。

Sure!当然!

All you have to do is use the parameterless flavor of case :您所要做的就是使用case的无参数风格:

select *
from my_table t
where t.col_1 = case
         when @var in (1,2,3) then "foo"
         when @var =   4      then "bar"
         when @var in (5,6,7) then "baz"
         else                      "bat"
       end

One might note that the when expressions are not limited to looking at the same variable in any way.人们可能会注意到when表达式不限于以任何方式查看相同的变量。 The only requirement is that they have to be a boolean expression.唯一的要求是它们必须是布尔表达式。 They're evaluated in order top to bottom.它们按照从上到下的顺序进行评估。 The first when clause that evaluates to true wins and it's then value is returned.第一个计算结果为true when子句获胜, then返回值。

If there's no else and evaluation fails to find a match, the result value is null .如果没有else并且评估未能找到匹配项,则结果值为null

Your problem though, is that case expressions不过,您的问题是case表达式

  • return a single value, and返回单个值,并且
  • that value must be of the same type.该值必须是相同的类型。 Can have it returning a string in some cases and a table variable in another.可以让它在某些情况下返回一个字符串,而在另一种情况下返回一个表变量。

So... your where clause should look something like this:所以......你的where子句应该是这样的:

where ...
  and 'true' = case
                 when @stringList = '' then 'true'
                 when ID in ( select *
                              from TurnListStringIntoTable(@stringList)
                            ) then 'true'
                 else 'false'
               end

You'll probably find, too, that invoking a user-defined function to convert a comma-delimited string into a table variable within the where clause is probably a Bad Idea™ due to the performance impact that that will have.您可能还会发现,调用用户定义的函数以将逗号分隔的字符串转换为where子句中的表变量可能是一个坏主意™,因为这会对性能产生影响。

You'd be better off to move your TurnListStringIntoTable call outside of the select statement, thus:您最好将TurnListStringIntoTable调用移到select语句之外,因此:

declare @list = TurnListStringIntoTable(@stringlist)

select ...
from ProjectTeam pt
where . . .
  and @stringlist = ''
   OR exists ( select * from @list x where x.ID = pt.ID )

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

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