【问题标题】:Filter SQL datatable according to different parameters, without a WHERE clause根据不同的参数过滤SQL数据表,不带WHERE子句
【发布时间】:2015-12-22 15:46:06
【问题描述】:

我正在构建一个应用程序,该应用程序需要允许用户根据不同的过滤器过滤数据表。因此,用户将拥有三种不同的过滤器可能性,但他可能只使用一种、两种或三种同时使用。

所以,假设我的桌子上有以下列:

ID(整数)PK

赛德(整数)

程序(整数)

Estado(整数)

所有这些列都将存储数字、整数。 “ID”列为主键,“Sede”存储1或2,“Programa”为1到15之间的任意数字,“Estado”存储1到13之间的数字。

用户可以使用任何过滤器(Sede、Programa 或 Estado)过滤存储在表中的数据。但也可以使用两个过滤器,或者同时使用三个过滤器。

这个想法是这个应用程序的工作方式类似于 Excel 上的数据过滤器。我在 excel 上创建了一个模拟表来显示我想要实现的目标:

第一张图片显示了整个表格,没有应用任何过滤器。

在这里,用户为“Sede”和“Programa”选择了一个过滤器,但将“Estado”过滤器留空。因此查询返回等于过滤器的值,但“Estado”过滤器保持打开状态,并带来所有记录,仅通过“Sede”(1)和“Programa”(6)归档。

在这张图片中,用户只选择了“Estado”过滤器(5),所以它会带来所有符合这个条件的记录,不管“Sede”或“Programa”是否为空。

如果我使用带有 WHERE 的 SELECT 子句,它将起作用,但前提是三个过滤器具有值:

DECLARE @sede int
DECLARE @programa int
DECLARE @estado int

SET @sede = '1'
SET @programa = '5'
SET @estado = '12'

SELECT * FROM [dbo].[Inscripciones]
WHERE
([dbo].[Inscripciones].[Sede] = @sede)
AND
([dbo].[Inscripciones].[Programa] = @programa)
AND
([dbo].[Inscripciones].[Estado] = @estado)

我也尝试将“AND”更改为“OR”,但无法获得所需的结果。

任何帮助将不胜感激!谢谢!

【问题讨论】:

  • 简单的方法就是使用 case 并检查 sede 或 programa 或 estado 是否为空,如果为空,请在 or 子句中使用,非空字段应在 and 子句中
  • 服务器端的下一个想法它自己可以验证它,您知道表列名称,因此从服务器端传递 where 子句并在此处使用动态 sql,因此仅包含非空字段where 子句,从 sql 你也可以做同样的事情,唯一的事情是你必须为这个 sol 使用动态 sql

标签: sql-server select filter


【解决方案1】:

常见问题:尝试在变量上使用合并,第二个值使用您要比较的字段名称。不过要小心;确保传递的是 NULL 而不是 empty string

它的作用是获取传入变量的第一个非空值或您要与之比较的值。因此,如果传入的值为 null,则比较将始终返回 true。

WHERE
[dbo].[Inscripciones].[Sede] = coalesce(@sede, [dbo].[Inscripciones].[Sede])
AND
[dbo].[Inscripciones].[Programa] = coalesce(@programa, [dbo].[Inscripciones].[Programa])
AND
[dbo].[Inscripciones].[Estado] = coalesce(@estado, [dbo].[Inscripciones].[Estado])

如果 sede 为 null 并且填充了 programa 和 estado,则比较看起来像...

?=? (or 1=1)
?=programa variable passed in
?=Estado variable passed in

Boa Sorte!

【讨论】:

  • 值得在本文中添加一个链接,该链接非常详细地讨论了这种捕获所有查询的类型以及处理其最终性能问题的一些方法。 sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries
  • 很棒的文章@SeanLange。这篇文章更全面地回应了这种方法对更大数据的性能副作用。
  • @SeanLange 谢谢!那篇文章给了我解决这个问题的所有线索。
【解决方案2】:

谢谢大家的回答。在阅读了@SeanLange 在 cmets 中发布的文章后,我终于能够实现所需要的。在 WHERE 语句中使用 CASE 子句可以解决问题。代码如下:

SELECT
    *
FROM [dbo].[Inscripciones] 
WHERE
    ([dbo].[Inscripciones].[Sede] = (CASE WHEN @sede = '' THEN [dbo].[Inscripciones].[Sede] ELSE @sede END))
    AND
    ([dbo].[Inscripciones].[Programa] = (CASE WHEN @programa = '' THEN [dbo].[Inscripciones].[Programa] ELSE @programa END))
    AND
    ([dbo].[Inscripciones].[Estado] = (CASE WHEN @estado = '' THEN [dbo].[Inscripciones].[Estado] ELSE @estado END))
    AND
    ([dbo].[Inscripciones].[TipoIngreso] = (CASE WHEN @tipoingreso = '' THEN [dbo].[Inscripciones].[TipoIngreso] ELSE @tipoingreso END))

再次感谢!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2014-09-19
    相关资源
    最近更新 更多