0

考虑以下

Declare @t table(Val int, name varchar(100))
Insert into @t select 1,'name1' 
union all select 1,'name2' 
union all select 2,'name3'
union all select 3,'name4'

如果我想获得与 Val 1 或 2 有关的记录,则选择是 IN 子句。但是我们有一些条件,需要根据这些条件选择值。此后,我们将继续采用 CASE 方法,如下所示

declare @type int  = 1
select *
from @t 
where val  = case when @type =1 then 1  end or
      val  = case when @type =1 then 2
             end

它可以作为select * from @t where val in (1,2)正常工作(我们不能使用它,因为必须在运行时确定值,并且我们没有使用任何动态查询)。有没有其他方法可以模拟 IN 子句?

这只是为了知识。

谢谢

4

2 回答 2

1

假设您的代码将单个值作为参数,但该值与值列表相关,您可以只使用映射表...

CREATE PROCEDURE pseudo_in_clause (@type INT)
AS

DECLARE @map TABLE (
  type  INT,
  val   INT,
  PRIMARY KEY (type, val)
)

INSERT INTO @map (type, val) VALUES (1, 1),
                                    (1, 2),
                                    (2, 3)

SELECT
  *
FROM
  yourTable      AS data
INNER JOIN
  @map           AS map
    ON data.val = map.val
WHERE
  map.type = @type

映射可以是永久表、临时表(如上)、函数等。

或者,您仍然可以在 CASE 语句中使用 IN 子句...

SELECT
  *
FROM
  yourTable      AS data
WHERE
  CASE WHEN @type = 1 AND data.val IN (1,2) THEN 1
       WHEN @type = 2 AND data.val IN (3,4) THEN 1
                                            ELSE 0
  END = 1

我个人更喜欢这个JOIN版本。

于 2012-06-22T06:43:47.540 回答
0

必须使用CASE吗?这也应该有效:

…
WHERE @type = 1 AND data.val IN (1, 2)
   OR @type = … AND data.val IN (…)
   OR …

尽管我必须说我最喜欢@Dems 关于使用连接的建议。请注意,您可以使用内联表而不是表变量,从而使整个事情成为单个查询:

SELECT *
FROM yourTable AS data
  INNER JOIN (
    VALUES
      (1, 1),
      (1, 2),
      (2, 3)
  ) AS map ON data.val = map.val
WHERE map.type = @type
于 2012-06-22T11:32:00.510 回答