1

我建立了一个界面,用户从数据库中获取记录。用户可以选择指定 0 个或多个过滤器。有四个过滤器A,B,C,D(假设这些是某个表中的字段)

这是我的查询应该是这样的:

select * from table 
where (A = v1 or B = v2 or C = v3) and D = v4

我试图用一种方法来制定查询,而当指定一个特定的过滤器时,它会被应用,如果不是,它会被忽略。但这应该适用于所有 16 种情况。

到目前为止,我能够想出的是这些方法:

select * from table
where (
    (A = v1 and 1)
    or (B =  v2 and 1)
    or (C = v3 and 1)
    )
    and D = v4

v1或其他值在未指定时设置为 -1。因此,如果未指定它们,它们将被简单地忽略,因为随后会使用另一个过滤器(来自 A、B、C)。但是在没有指定 A、B 和 C 的情况下,这将失败。在这种情况下,false 与 D 进行 Anded,并且不应用 D。

有没有办法为这种情况提供 where 子句?我也对这个程序的解决方案持开放态度,我通过代码添加或不添加子句,但我更喜欢这种方式。而且我真的不想有很多 if-else 语句。

谢谢!

4

3 回答 3

1

case使用构造怎么样

  select * 
  from table
  where (A = CASE WHEN v1 IS NOT NULL THEN v1 else '' END)
            OR (B =  CASE WHEN v2 IS NOT NULL THEN v2 else '' END)
            OR (C = CASE WHEN v3 IS NOT NULL THEN v3 else '' END)
            OR (CASE WHEN v1 is null and v2 is null and v3 is null then 1 else 0 end)
  and D = v4
于 2012-06-12T07:38:06.077 回答
0

数据库很难优化动态 where 子句。通常,他们会制定一个最适合第一次调用的计划。因此,如果您的第一次搜索是过滤器 A 和 B,则查询计划将为此进行优化。下一个查询也将使用该计划,即使它使用过滤器 C 和 D。在代码中添加 where 子句往往会执行得更好。

但这是可能的,例如:

where  (
           A = @FilterAValue
           or B = @FilterBValue
           or C = @FilterCValue
       )
       and D = coalesce(@FilterDValue, D)

然后您可以使用参数切换过滤器FilterXValue。如果 A、B 或 C 的过滤器是,则仍将评估 null的其他部分。与which is only true when相同。orA = null or B = 1unknown or B = 1B = 1

于 2012-06-12T07:39:10.093 回答
0

if v1-v4是您正在搜索的值,-1如果未指定所有这些值,您可以这样做:

SELECT
  *
FROM
  table
WHERE
  (
    (A = v1 OR -1 = v1)
  or 
    (B =  v2 OR -1 = v2)
  or 
    (C = v3 OR -1 = v3)
  )
AND
  (D = v4 OR -1 = v4)
于 2012-06-12T07:40:51.207 回答