65.9K
CodeProject 正在变化。 阅读更多。
Home

WHERE 子句中的多个过滤器

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.63/5 (8投票s)

2005年5月2日

6分钟阅读

viewsIcon

52145

如何在 SQL 语句的 WHERE 子句中编写多个过滤器。

WHERE 子句中的多个过滤器


引言

 

有时我需要开发一个报表或一些显示数据的东西,但之前用户可以应用多个筛选器,以便查看想要查找的信息。

我一如既往地设计了带有筛选器的用户界面,然后将筛选器传递到不同的层,最后,它们到达了一个存储过程,该存储过程进行查询。

它返回数据,仅此而已。

 

我曾多次听到一些同事说,他们必须显示应用了多个筛选器的数据,但最终在存储过程中,他们除了通过构建字符串然后使用 EXEC sql 命令执行它,或者制作多个 SELECT 语句之外,找不到其他方法来构建查询。

 

示例

 

以 pubs 数据库为例说明这种情况。

 

 

我们必须显示属于某个出版商或拥有特定职位的员工。

用户界面如下所示

 

 

 

您可以通过选择职位或(所有职位)来筛选职位,也可以通过选择出版商或(所有出版商)来筛选出版商。

 

解决查询的存储过程大致如下所示

 

制作多个 SELECT 语句

 

 

CREATE PROCEDURE dbo.GetEmployeesFiltered1

 

      (

            @JobFilter int ,

            @PublisherFilter int

      )

 

AS

     

      begin

     

      declare @FilterByJob bit

      declare @FilterByPub bit

 

      if  @JobFilter > 0

            begin

                  select @FilterByJob = 1

            end

      else

            begin

                  select @FilterByJob = 0

            end

           

      if  @PublisherFilter > 0

            begin

                  select @FilterByPub = 1

            end

      else

            begin

                  select @FilterByPub = 0

            end

           

           

           

           

           

           

           

           

           

           

      if @FilterByJob=1

            BEGIN

                  if @FilterByPub=1

                        BEGIN

                              --按职位和出版商筛选

                              SELECT     jobs.job_desc AS Expr1, publishers.pub_name AS Expr2, employee.*

                              FROM       jobs INNER JOIN

                                          employee ON jobs.job_id = employee.job_id INNER JOIN

                                          publishers ON employee.pub_id = publishers.pub_id

                                      

                              WHERE

                                    publishers.pub_id = @PublisherFilter

                                    或者

                                    jobs.job_id = @JobFilter

               

                        END

                       

                  else

                        --按职位筛选

                        BEGIN

                 

                              SELECT     jobs.job_desc AS Expr1, publishers.pub_name AS Expr2, employee.*

                              FROM       jobs INNER JOIN

                                          employee ON jobs.job_id = employee.job_id INNER JOIN

                                          publishers ON employee.pub_id = publishers.pub_id

                                      

                              WHERE

                                        jobs.job_id = @JobFilter

                        END

 

            END

 

      else

            --不按职位筛选

 

            BEGIN

                  if @FilterByPub=1

                        BEGIN

                 

                              SELECT     jobs.job_desc AS Expr1, publishers.pub_name AS Expr2, employee.*

                              FROM       jobs INNER JOIN

                                          employee ON jobs.job_id = employee.job_id INNER JOIN

                                          publishers ON employee.pub_id = publishers.pub_id

                                      

                              WHERE

                                    publishers.pub_id = @PublisherFilter

               

                        END

                  else

                        --不按出版商筛选

                        BEGIN

                 

                              SELECT     jobs.job_desc AS Expr1, publishers.pub_name AS Expr2, employee.*

                              FROM       jobs INNER JOIN

                                          employee ON jobs.job_id = employee.job_id INNER JOIN

                                          publishers ON employee.pub_id = publishers.pub_id

               

                        END

 

            END

           

           

 

 

      end

 

     

 

这类过程的问题在于维护起来很麻烦,您必须记住为所有选项/筛选器维护 SELECT 语句。

 

 

所以可以用这种方式解决

 

 

通过 EXEC 命令执行构建的 SELECT 语句

 

 

CREATE PROCEDURE dbo.GetEmployeesFiltered2

 

      (

            @JobFilter int ,

            @PublisherFilter int

      )

 

AS

     

      begin

     

      declare @FilterByJob bit

      declare @FilterByPub bit

 

      if  @JobFilter > 0

            begin

                  select @FilterByJob = 1

            end

      else

            begin

                  select @FilterByJob = 0

            end

           

      if  @PublisherFilter > 0

            begin

                  select @FilterByPub = 1

            end

      else

            begin

                  select @FilterByPub = 0

            end

           

           

           

      declare @mySentece varchar (1000)        

      declare @myFilter varchar (1000)

     

     

     

      select @mySentece = 'SELECT     jobs.job_desc AS Expr1, publishers.pub_name AS Expr2, employee.*

                              FROM       jobs INNER JOIN

                                          employee ON jobs.job_id = employee.job_id INNER JOIN

                                          publishers ON employee.pub_id = publishers.pub_id'

 

     

     

     

     

      if @FilterByJob=1

            BEGIN

                  if @FilterByPub=1

                        BEGIN

                              --按职位和出版商筛选

                              SELECT     @myFilter = 'publishers.pub_id = ' + @PublisherFilter + '

                                    OR

                                    jobs.job_id = ' + @JobFilter

                        END

                       

                  else

                        --按职位筛选

                        BEGIN            

                              SELECT     @myFilter = 'jobs.job_id = ' + @JobFilter

                        END

 

            END

 

      else

            --不按职位筛选

 

            BEGIN

                  if @FilterByPub=1

                        BEGIN

                 

                              SELECT     @myFilter = 'publishers.pub_id = ' + @PublisherFilter

               

                        END

                  else

                        --不按出版商筛选

                        BEGIN            

                              SELECT     @myFilter = ''

                        END

            END

           

 

      end

 

 

 

      if @myFilter = ''

            begin

                  exec ( @mySentece )

            end

      else

            begin

                  exec ( @mySentece + ' WHERE ' + @myFilter )

            end

 

     

 

 

     

 

这里解决了为所有选项/筛选器维护 SELECT 语句的问题,但它存在 SQL Server 必须在每次执行时编译存储过程的问题。

 

 

 

多重筛选 SELECT 语句

 

这就是我提出的带有 多个筛选器的查询解决方案

 

 

 

CREATE PROCEDURE dbo.GetEmployeesFiltered3

 

      (

            @JobFilter int ,

            @PublisherFilter int

      )

 

AS

     

      begin

     

      declare @FilterByJob bit

      declare @FilterByPub bit

 

      if  @JobFilter > 0

            begin

                  select @FilterByJob = 1

            end

      else

            begin

                  select @FilterByJob = 0

            end

           

      if  @PublisherFilter > 0

            begin

                  select @FilterByPub = 1

            end

      else

            begin

                  select @FilterByPub = 0

            end

           

           

           

     

      SELECT     jobs.job_desc AS Expr1, publishers.pub_name AS Expr2, employee.*

                              FROM       jobs INNER JOIN

                                          employee ON jobs.job_id = employee.job_id INNER JOIN

                                          publishers ON employee.pub_id = publishers.pub_id

 

                  WHERE            

                        (@FilterByPub=1 AND publishers.pub_id = @PublisherFilter )

                       

                        或者

                       

                        (@FilterByJob=1 AND jobs.job_id = @JobFilter )

      End

 

 

 

 

主要步骤是确定要“激活”哪些筛选器。当此指示器打开时,它将应用 WHERE 搜索条件。

这是在 WHERE 子句中构建多个筛选器的诀窍。

 

 

 

 

关于 fhunth

Sample image

 

最近,我受雇于 Huddle Group (http://www.huddle.com.ar/) 担任 C# 高级开发人员

联系我:

-fhunth@hotmail.com

-fernando@huddle.com.ar

 

访问我的博客:

http://msdevelopers.blogspot.com/

 

© . All rights reserved.