SQL 优化 where 子句中的条件

Posted

技术标签:

【中文标题】SQL 优化 where 子句中的条件【英文标题】:SQL optimise conditions in where clause 【发布时间】:2013-09-22 15:19:49 【问题描述】:

在 asp 中,我设置了几个下拉菜单,允许用户根据他们的选择过滤页面上显示的数据。

这些下拉菜单用于数据收集、年级组(例如 11 年级)、科目(例如英语)、教学组和子组。

必须选择数据收集、年份和主题,但教学组和子组可以保持未选择(全选)、单独选择或同时选择。

由于子组下有许多选项,我在 SQL 存储过程中的 where 子句现在很大。以下是几个选项,其中未选择子组或选择了女孩子组或选择了男孩子组。还有很多,但为了简洁起见,我限制了我发布的内容。

我的问题是我可以以任何方式优化此代码还是最简洁?如果您需要更多示例,请告诉我,我会将它们添加到帖子中。

where 

--All
(@TeachingGroup = 'Select All' AND ([StuYear] = @StuYear) AND ([DataCollection] = @DataCollection) AND ([Name] = @SubjectName)  AND @Subgroup='Select All'
OR 
@TeachingGroup <> 'Select All' AND ([StuYear] = @StuYear) AND ([DataCollection] = @DataCollection) AND ([Name] = @SubjectName) AND ([TeachingGroup] = @TeachingGroup)  AND @Subgroup='Select All')
or
--Gender Girls
(@TeachingGroup = 'Select All' AND ([StuYear] = @StuYear) AND ([DataCollection] = @DataCollection) AND ([Name] = @SubjectName)  AND Gender = 
case when @Subgroup = 'GenF' then 'F' end)
OR 
@TeachingGroup <> 'Select All' AND ([StuYear] = @StuYear) AND ([DataCollection] = @DataCollection) AND ([Name] = @SubjectName) AND ([TeachingGroup] = @TeachingGroup)  AND Gender = case when @Subgroup = 'GenF' then 'F' end
or
--Gender boys
(@TeachingGroup = 'Select All' AND ([StuYear] = @StuYear) AND ([DataCollection] = @DataCollection) AND ([Name] = @SubjectName)  AND Gender = 
case when @Subgroup = 'GenM' then 'M' end)
OR 
@TeachingGroup <> 'Select All' AND ([StuYear] = @StuYear) AND ([DataCollection] = @DataCollection) AND ([Name] = @SubjectName) AND ([TeachingGroup] = @TeachingGroup)  AND Gender = case when @Subgroup = 'GenM' then 'M' end

【问题讨论】:

【参考方案1】:

如果您获得更多条件,您可能需要研究动态 SQL,根据提供的内容构建不同的查询。

此外,将“Null”传递给“全选”是相当标准的做法

但是,这是您所拥有的更简单的版本:

Where
    [StuYear] = @StuYear And
    [DataCollection] = @DataCollection And
    [Name] = @SubjectName And (
        @TeachingGroup = 'Select All' Or 
        [TeachingGroup] = @TeachingGroup
    ) And (
       @SubGroup = 'Select All' Or
       Gender = Case 
               When @SubGroup = 'GenF' Then 'F'
               When @SubGroup = 'GenM' Then 'M'
           End
    )

动态 sql 示例

Declare 
    @params nvarchar(max) = '
@StuYear int,
@DataCollection varchar(30),
@SubjectName varchar(30),
@TeachingGroup varchar(30),
@SubGroup varchar(30)', --replace with your definitions
    @sql nvarchar(max) = '
Select 
    xxx 
from 
    xxx 
Where
    [StuYear] = @StuYear And
    [DataCollection] = @DataCollection And
    [Name] = @SubjectName'

If @TeachingGroup != 'Select All'
   Set @sql += ' And TeachingGroup = @TeachingGroup'

If @SubGroup != 'Select All'
   Set @sql += ' And Gender = Right(@SubGroup, 1)'

Exec sp_executesql @sql, @params, 
    @StuYear, @DataCollection, @SubjectName, @TeachingGroup, @SubGroup

【讨论】:

这个答案对我有用。我也喜欢它有两种选择供我尝试,所以我会考虑在未来使用动态 sql 方法,但现在标准结果可以正常工作。

以上是关于SQL 优化 where 子句中的条件的主要内容,如果未能解决你的问题,请参考以下文章

sql优化

sql语句中where后边的哪些条件会使索引失效 -- SQL语句优化

第 2 章 查询条件优化之等值查找

SQL通用优化方案(where优化索引优化分页优化事务优化临时表优化)

优化where子句中的SQL子查询

WHERE 子句中的 SQL 查询子选择优化 (SQL Server)