sta*_*ser 9 t-sql sql-server sql-server-2005
我想根据一个编码在CTE中执行select语句.类似下面的东西
;with CTE_AorB
(
if(condition)
select * from table_A
else
select * from table_B
),
CTE_C as
(
select * from CTE_AorB // processing is removed
)
Run Code Online (Sandbox Code Playgroud)
但我得到错误.如果在CTE中有其他可能吗?如果不是有解决方案或更好的方法.
谢谢.
KM.*_*KM. 22
尝试:
;with CTE_AorB
(
select * from table_A WHERE (condition true)
union all
select * from table_B WHERE NOT (condition true)
),
CTE_C as
(
select * from CTE_AorB // processing is removed
)
Run Code Online (Sandbox Code Playgroud)
具有动态搜索条件的键是确保使用索引,这是一篇关于如何处理此主题的非常全面的文章:
Erland Sommarskog在T-SQL中的动态搜索条件
它涵盖了尝试使用多个可选搜索条件编写查询的所有问题和方法.您需要关注的主要问题不是代码的重复,而是索引的使用.如果您的查询无法使用索引,那么它将执行不良.有几种技术可以使用,它们可能允许也可能不允许使用索引.
这是目录:
Introduction
The Case Study: Searching Orders
The Northgale Database
Dynamic SQL
Introduction
Using sp_executesql
Using the CLR
Using EXEC()
When Caching Is Not Really What You Want
Static SQL
Introduction
x = @x OR @x IS NULL
Using IF statements
Umachandar's Bag of Tricks
Using Temp Tables
x = @x AND @x IS NOT NULL
Handling Complex Conditions
Hybrid Solutions – Using both Static and Dynamic SQL
Using Views
Using Inline Table Functions
Conclusion
Feedback and Acknowledgements
Revision History
如果您使用的是适当版本的SQL Server 2008,则可以使用其他技术,请参阅:SQL 2008的T-SQL版本中的动态搜索条件(SP1 CU5及更高版本)
如果您使用的是SQL Server 2008的正确版本,则可以添加OPTION (RECOMPILE)到查询中,并在运行时将局部变量的值用于优化.
考虑一下,OPTION (RECOMPILE)将采用这个代码(没有索引可以用于这个混乱的ORs):
WHERE
(@search1 IS NULL or Column1=@Search1)
AND (@search2 IS NULL or Column2=@Search2)
AND (@search3 IS NULL or Column3=@Search3)
Run Code Online (Sandbox Code Playgroud)
并在运行时优化它(假设只有@ Search2传入一个值):
WHERE
Column2=@Search2
Run Code Online (Sandbox Code Playgroud)
并且可以使用索引(如果在Column2上定义了一个索引)
切勿尝试将 IF 等条件放入单个查询语句中。即使你确实成功了,这也是一种肯定会降低性能的方法。请记住,单个语句意味着单个计划,并且必须以同时满足两种情况(当条件为真和当条件为假时)的方式生成计划。这通常会导致更糟糕的计划,因为“条件”通常会为计划创建互斥的访问路径,并且两者的并集始终导致端到端表扫描。
出于这个原因和许多其他原因,最好的方法是将 IF 移出语句之外:
if(condition true)
select * from table_A
else
select * from table_B
Run Code Online (Sandbox Code Playgroud)