SQL Server 2008 - SELECT 子句中的 Case / If 语句 [重复]
Posted
技术标签:
【中文标题】SQL Server 2008 - SELECT 子句中的 Case / If 语句 [重复]【英文标题】:SQL Server 2008 - Case / If statements in SELECT Clause [duplicate] 【发布时间】:2010-11-10 11:44:09 【问题描述】:我有一个应该像这样运行的查询 -
如果(变量 = xyz) 选择 col1,col2 否则 IF(var = zyx) 选择 col2,col3 别的 选择 col7,col8 从 . . .如何在不为每个子句编写单独查询的情况下在 T-SQL 中实现这一点?目前我正在运行它
如果 (var = xyz) 查询1 否则 IF (var = zyx) 查询2 别的 查询3这只是根据值选择不同列的大量冗余代码。 有其他选择吗?
【问题讨论】:
【参考方案1】:您正在寻找 CASE 声明
http://msdn.microsoft.com/en-us/library/ms181765.aspx
从 MSDN 复制的示例:
USE AdventureWorks;
GO
SELECT ProductNumber, Category =
CASE ProductLine
WHEN 'R' THEN 'Road'
WHEN 'M' THEN 'Mountain'
WHEN 'T' THEN 'Touring'
WHEN 'S' THEN 'Other sale items'
ELSE 'Not for sale'
END,
Name
FROM Production.Product
ORDER BY ProductNumber;
GO
【讨论】:
看来我是忍者了! :) 我仍然是一个 n00b,所以我可能(很容易)错了,但我认为这实际上并不能回答问题,对吧? OP 询问他如何选择 multiple 列,而不是将值的几个选项之一分配给单个列,这似乎(以及几个答案)正在这样做。如果我是 OP,那么@JoelMansford 的答案似乎是最正确的。如果我错了,请告诉我/为什么我错了!【参考方案2】:请注意,出于优化的原因,您实际上最好使用 3 个单独的 SELECTS。如果您只有一个 SELECT,那么生成的计划将必须投影所有列 col1、col2、col3、col7、col8 等,尽管根据运行时@var 的值,只需要一些列。这可能会导致执行不必要的聚集索引查找的计划,因为非聚集索引不会覆盖 SELECT 投影的所有列。
另一方面,3 个单独的 SELECTS,每个仅投影所需的列可能会受益于在每种情况下仅覆盖您的投影列的非聚集索引。
当然,这取决于您的数据模型的实际架构和确切的查询,但这只是一个提示,因此您不会将过程编程的命令式思维思维框架带入 SQL 的声明式世界。
【讨论】:
+1 非常好的观察【参考方案3】:试试类似的东西
SELECT
CASE var
WHEN xyz THEN col1
WHEN zyx THEN col2
ELSE col7
END AS col1,
...
换句话说,使用条件表达式选择值,然后重命名列。
或者,您可以构建某种动态 SQL hack 来共享查询尾部;我以前用 iBatis 做过。
【讨论】:
【参考方案4】:简单的 CASE 表达式:
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
搜索到的 CASE 表达式:
CASE
WHEN Boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
参考:http://msdn.microsoft.com/en-us/library/ms181765.aspx
【讨论】:
【参考方案5】:CASE 是答案,但您需要为要返回的每一列单独使用 case 语句。只要 WHERE 子句相同,将其拆分为多个查询不会有太多好处。
例子:
SELECT
CASE @var
WHEN 'xyz' THEN col1
WHEN 'zyx' THEN col2
ELSE col7
END,
CASE @var
WHEN 'xyz' THEN col2
WHEN 'zyx' THEN col3
ELSE col8
END
FROM Table
...
【讨论】:
【参考方案6】:最明显的解决方案已经列出。根据查询所在的位置(即在应用程序代码中),您不能总是使用 IF 语句,并且内联 CASE 语句可能会在许多列成为条件的情况下变得痛苦。 假设 Col1 + Col3 + Col7 是相同的类型,同样 Col2, Col4 + Col8 你可以这样做:
SELECT Col1, Col2 FROM tbl WHERE @Var LIKE 'xyz'
UNION ALL
SELECT Col3, Col4 FROM tbl WHERE @Var LIKE 'zyx'
UNION ALL
SELECT Col7, Col8 FROM tbl WHERE @Var NOT LIKE 'xyz' AND @Var NOT LIKE 'zyx'
由于这是单个命令,因此在计划缓存方面有几个性能优势。此外,查询优化器将在不触及存储引擎的情况下快速消除那些 @Var 与适当值不匹配的语句。
【讨论】:
以上是关于SQL Server 2008 - SELECT 子句中的 Case / If 语句 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Sql Server 2008 获取用于插入到 select 中的 scope_identity 列表?