切换导航
简历
工具
演示
查询
导航菜单
服务端
30
前端
114
数据库
82
进阶开发
8
桌面程序
2
QA
15
软件使用
36
规范协议
5
操作系统
11
AI
0
复用资源
6
硬件
0
标签
SQL Server
Redis
MySQL
其它
Oracle
外部链接
.NET Core SDK和运行时安装包
淘宝 NPM 镜像
查询网
Tables Generator线上表格转换工具
引用cdn在线脚本和样式
首页
数据库
SQL Server T-SQL 语言元素 表达式
[TOC] ## 1. 表达式 符号和运算符的一种组合,SQL Server 数据库引擎将处理该组合以获得单个数据值。 简单表达式可以是一个常量、变量、列或标量函数。 可以用运算符将两个或更多的简单表达式联接起来组成复杂表达式。 > **适用于:**Microsoft Fabric、Warehouse 中的 SQL Server、Azure SQL 数据库、Azure SQL 托管实例、Azure Synapse、Analytics Analytics Platform System (PDW)、SQL Analytics 终结点 ### 1.1. 语法 下面只是 SQL Server 和 Azure SQL Database 产品的语法,至于其它数据库产品语法参见官方文档,在本文下面的参考可跳转 ```Bash { constant | scalar_function | [ table_name. ] column | variable | ( expression ) | ( scalar_subquery ) | { unary_operator } expression | expression { binary_operator } expression | ranking_windowed_function | aggregate_windowed_function } ``` **参数解释:** |参数|定义| |--|--| |*constant*|表示单个特定数据值的符号(常量)| |scalar_function|一个 Transact-SQL 语法单元,用于提供特定服务并返回单个值。 scalar_function 可以是内置标量函数(如 SUM、GETDATE 或 CAST 函数),也可以是标量用户定义函数| |[ table_name. ]|表的名称或别名| |*column*|列的名称。 表达式中只允许列的名称| |variable|变量或参数的名称| |( *expression* )|本主题中定义的任意一个有效表达式。 括号是分组运算符,用于确保先运算括号内表达式中的运算符,然后再将结果与别的表达式组合。| |( *scalar_subquery* )|返回一个值的子查询。 例如:`SELECT MAX(UnitPrice) FROM Products`| |(unary_operator)|一元运算符只能用于计算结果数据类型属于数字数据类型类别的表达式。 只有一个数字操作数的运算符:`+ 指示正数``- 指示负数``~ 指示一的补数运算符`| |{ binary_operator }|用于定义如何组合两个表达式以得到一个结果的运算符。 binary_operator 可以是算术运算符、赋值运算符 (=)、位运算符、比较运算符、逻辑运算符、字符串连接运算符 (+) 或一元运算符| |ranking_windowed_function|任意 T-SQL [排名函数](https://learn.microsoft.com/zh-cn/sql/t-sql/functions/ranking-functions-transact-sql?view=sql-server-ver16)| |aggregate_windowed_function|任意包含 OVER 子句的 T-SQL [聚合函数](https://learn.microsoft.com/zh-cn/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-ver16)| ### 1.2. 表达式结果 #### 1.2.1. 单个元素的简单表达式结果 对于由单个常量、变量、标量函数或列名组成的简单表达式,其数据类型、排序规则、精度、小数位数和值就是它所引用的元素的数据类型、排序规则、精度、小数位数和值,通俗的讲就是这个表达式的属性(如数据类型、排序规则、精度、小数位数等)将直接继承自该元素 |Element|Data Type|Collation|Precision/Scl| Value| |---------------------|------------------|---------------|----------------|----------------| | Constant: 5 | int | Not Applicable| Not Applicable | 5 | | Variable: @myDecimal| decimal(10, 2) | Not Applicable| 10/2 | Depends | | Scalar Function: GETDATE()| datetime| Not Applicable| Not Applicable | Current Date & Time | | Column: Employee.Salary | money | Not Applicable| Not Applicable | Depends | | Column: Customer.Name | nvarchar(50) | Latin1_General_CI_AS| Not Applicable | Depends | #### 1.2.2. 结果为布尔数据类型的表达式结果 用比较运算符或逻辑运算符组合两个表达式时,生成的数据类型为 Boolean,并且值为下列类型之一:TRUE、FALSE 或 UNKNOWN 在 SQL Server 中,并没有一个明确的布尔数据类型(Boolean),但是 T-SQL 支持使用比较运算符(如 `=`, `<`, `>`, `<=`, `>=`, `<>` 或 `!=`)和逻辑运算符(如 `AND`, `OR`, `NOT`)来创建表达式,这些表达式的结果通常被解释为布尔值。在 SQL Server 中,布尔值的结果通常是以整数的形式表示的,其中: - **TRUE** 被表示为 `1` - **FALSE** 被表示为 `0` - **UNKNOWN** 被表示为 `NULL` 这种设计是因为 SQL Server 以及许多其他数据库系统都遵循了 SQL 标准中的“三值逻辑”(Three-Valued Logic, TVL)。这意味着除了真和假之外,SQL 还处理未知状态,这通常是由于 NULL 值的出现而引起的。 例如,如果你有一个查询,它试图比较一个可能含有 NULL 值的列,那么如果列中的某一行确实为 NULL,比较的结果将不会是 TRUE 或 FALSE,而是 UNKNOWN,这是因为无法确定 NULL 是否等于任何特定的值。 下面是一些使用 T-SQL 比较和逻辑运算符的例子: |项|示例| |--|--| |比较运算符|`SELECT * FROM Customers WHERE Age = 30;`<br>如果某行的 Age 字段等于 30,则返回该行,否则不返回 <div style="border-bottom:1px dashed #a7a7a7;margin:6px 0px"></div>`SELECT * FROM Orders WHERE OrderDate > '2023-01-01';` <br>如果某行的 OrderDate 大于 '2023-01-01',则返回该行,否则不返回| |逻辑运算符|`SELECT * FROM Products WHERE Quantity > 0 AND Price < 100;`<br>返回所有数量大于 0 并且价格小于 100 的产品。<div style="border-bottom:1px dashed #a7a7a7;margin:6px 0px"></div>`SELECT * FROM Employees WHERE Salary >= 50000 OR DepartmentID = 10;`<br>返回所有工资大于等于 50000 或者部门编号为 10 的员工| |处理 NULL 的情况|`SELECT * FROM Users WHERE UserName IS NOT NULL;`<br>返回所有非空用户名的用户记录| 当使用逻辑运算符时,SQL Server 会遵循短路逻辑原则,这意味着如果第一个条件就能确定整个表达式的真假性,那么第二个条件就不会被评估。例如,在 `A AND B` 的情况下,如果 A 为 FALSE,则不会评估 B,因为整个表达式已经是 FALSE 了。 > 因此,在 SQL Server 中处理布尔逻辑时,理解 NULL 的行为及其对结果的影响是非常重要的。 #### 1.2.3. 运算符组合表达式结果 用算术运算符、位运算符或字符串运算符组合两个表达式时,生成的数据类型取决于运算符,以下是对各种运算符和它们影响数据类型方式的解释 <table><tr><td>运算符</td><td>说明</td></tr><tr><td>算术运算符</td><td>算术运算符包括加法 (+), 减法 (-), 乘法 (\*), 除法 (/), 和取模 (MOD 或 %)。在组合两个数值表达式时,数据类型通常会被提升到更宽泛的类型,以防止数据丢失,示例:<pre class="prettyprint linenums prettyprinted" style=""><ol class="linenums"><li class="L0"><code class="lang-SQL"><span class="pun">--</span><span class="pln"> </span><span class="pun">整数与整数相加,结果仍为整数</span></code></li><li class="L1"><code class="lang-SQL"><span class="pln">SELECT </span><span class="lit">1</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> AS </span><span class="typ">Result</span><span class="pun">;</span></code></li><li class="L2"><code class="lang-SQL"></code></li><li class="L3"><code class="lang-SQL"><span class="pun">--</span><span class="pln"> </span><span class="pun">小数与小数相加,结果为小数</span></code></li><li class="L4"><code class="lang-SQL"><span class="pln">SELECT </span><span class="lit">1.0</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2.0</span><span class="pln"> AS </span><span class="typ">Result</span><span class="pun">;</span></code></li><li class="L5"><code class="lang-SQL"></code></li><li class="L6"><code class="lang-SQL"><span class="pun">--</span><span class="pln"> </span><span class="pun">整数与小数相加,结果提升为小数</span></code></li><li class="L7"><code class="lang-SQL"><span class="pln">SELECT </span><span class="lit">1</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2.0</span><span class="pln"> AS </span><span class="typ">Result</span><span class="pun">;</span></code></li></ol></pre></td></tr><tr><td>位运算符</td><td>位运算符用于按位操作整数表达式,包括 AND (&), OR (|), XOR (^), NOT (~), 左移 (<<) 和右移 (>>),示例:<pre class="prettyprint linenums prettyprinted" style=""><ol class="linenums"><li class="L0"><code class="lang-SQL"><span class="pun">--</span><span class="pln"> </span><span class="pun">按位与运算</span></code></li><li class="L1"><code class="lang-SQL"><span class="pln">SELECT </span><span class="lit">15</span><span class="pln"> </span><span class="pun">&</span><span class="pln"> </span><span class="lit">7</span><span class="pln"> AS </span><span class="typ">Bitwise_AND_Result</span><span class="pun">;</span></code></li><li class="L2"><code class="lang-SQL"></code></li><li class="L3"><code class="lang-SQL"><span class="pun">--</span><span class="pln"> </span><span class="pun">按位或运算</span></code></li><li class="L4"><code class="lang-SQL"><span class="pln">SELECT </span><span class="lit">15</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="lit">7</span><span class="pln"> AS </span><span class="typ">Bitwise_OR_Result</span><span class="pun">;</span></code></li><li class="L5"><code class="lang-SQL"></code></li><li class="L6"><code class="lang-SQL"><span class="pun">--</span><span class="pln"> </span><span class="pun">按位异或运算</span></code></li><li class="L7"><code class="lang-SQL"><span class="pln">SELECT </span><span class="lit">15</span><span class="pln"> </span><span class="pun">^</span><span class="pln"> </span><span class="lit">7</span><span class="pln"> AS </span><span class="typ">Bitwise_XOR_Result</span><span class="pun">;</span></code></li></ol></pre></td></tr><tr><td>字符串运算符</td><td>主要的字符串运算符是连接运算符 (+ 或 CONCAT),用于连接两个字符串表达式,示例:<pre class="prettyprint linenums prettyprinted" style=""><ol class="linenums"><li class="L0"><code class="lang-sql"><span class="pun">--</span><span class="pln"> </span><span class="pun">使用</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="pun">连接两个字符串</span></code></li><li class="L1"><code class="lang-sql"><span class="pln">SELECT </span><span class="str">'Hello'</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">' World'</span><span class="pln"> AS </span><span class="typ">Concatenation_Result</span><span class="pun">;</span></code></li><li class="L2"><code class="lang-sql"></code></li><li class="L3"><code class="lang-sql"><span class="pun">--</span><span class="pln"> </span><span class="pun">使用</span><span class="pln"> CONCAT </span><span class="pun">函数连接两个字符串</span></code></li><li class="L4"><code class="lang-sql"><span class="pln">SELECT CONCAT</span><span class="pun">(</span><span class="str">'Hello'</span><span class="pun">,</span><span class="pln"> </span><span class="str">' World'</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">Concatenation_Result</span><span class="pun">;</span></code></li></ol></pre></td></tr></table> **数据类型转换规则** + 当执行算术运算时,SQL Server 遵循类型优先级,从低到高依次是: tinyint, smallint, int, bigint, decimal, numeric, float, real, money, smallmoney,其中较低的数据类型可以自动提升至较高的数据类型以适应运算。例如,当我们执行一个涉及 `int` 和 `float` 的加法时,`int` 会自动提升为 `float`,然后进行加法运算 + 对于字符串运算,SQL Server 可能需要将非字符串类型转换为字符串类型才能执行连接。 #### 1.2.4. 复杂表达式结果 由多个符号和运算符组成的复杂表达式的计算结果为单值结果。 生成的表达式的数据类型、排序规则、精度和值由进行组合的两个表达式决定,并按每次两个表达式的顺序递延,直到得出最后结果。 表达式中元素组合的顺序由表达式中运算符的优先级决定 在 SQL Server 中,当 T-SQL 表达式涉及多个运算符和不同数据类型的值时,其计算过程遵循一定的规则来确定最终结果的数据类型、排序规则(即字符集和比较规则)、精度和标度。这些规则可以概括如下: |规则|说明| |--|--| |运算符优先级|SQL Server 有预定义的运算符优先级列表,这决定了表达式中先计算什么后计算什么。例如,乘法和除法通常优先于加法和减法| |数据类型转换|当参与运算的两个表达式具有不同的数据类型时,SQL Server 将根据数据类型转换规则自动将它们转换为同一数据类型,以便进行计算。转换遵循从低到高的数据类型优先级| |精度和标度|对于数值类型,结果的精度和标度(小数点后的位数)也取决于操作数的数据类型和运算符| |排序规则|对于字符串或日期时间类型的表达式,结果的排序规则(collation)基于参与运算的操作数的排序规则,以及数据库或服务器的默认排序规则| **示例**: ```SQL -- 假设我们有以下表达式 SELECT (1 + CAST(3.14 AS DECIMAL(10, 2))) * 2; ``` 这里的运算符包括加号 (`+`) 和乘号 (`*`)。按照优先级,乘法 (`*`) 会先于加法 (`+`) 进行计算。 + **运算符优先级**:首先计算括号内的加法,然后执行乘法。 + **数据类型转换**:数字 `1` 是整数类型 (`INT`),而 `3.14` 被转换为 `DECIMAL(10, 2)` 类型。在加法之前,`1` 将被转换为与 `3.14` 相同的 `DECIMAL` 类型。 + **精度和标度**:在执行加法之后,结果将是 `DECIMAL(10, 2)` 类型,因为这是两个操作数中精度最高的。然后,这个 `DECIMAL` 类型的结果将与 `2` (也将被转换为 `DECIMAL` 类型)进行乘法运算。 + **排序规则**:在这个例子中不适用,因为我们只处理了数值类型。 最终结果将是一个 `DECIMAL` 类型的值,表示为 `(4.14 * 2)` 或者 `8.28` > **备注:** 两个或者多个表达式组合需要保证表达式都是同样的类型或可以隐式显示(CAST/CONVERT函数)的转换为相同的类型,否则是不允许组合的 ### 1.3. 使用表达式存在的问题 在SQL Server中,如果T-SQL语句中的表达式过长,可能会引起以下几个方面的问题: |问题|说明| |--|--| |**性能影响**|**1. **复杂的表达式可能会导致查询计划优化器难以快速找到最优的执行计划,从而影响查询性能。<br/>**2. **如果表达式包含大量的函数调用或复杂的算术运算,那么CPU的计算负担会增加,这可能导致查询执行变慢。| |**资源消耗**|**1. **长表达式可能占用更多的内存,特别是在解析和编译阶段,如果表达式非常复杂,可能需要较大的工作区内存。<br/>**2. **如果表达式中包含大量的字符串拼接或转换,可能会产生较多的临时对象和中间结果,这也增加了对系统资源的需求。| |**可读性和维护性**|**1. **过长的表达式降低了代码的可读性,使得理解和维护变得更加困难。<br/>**2. **当需要修改表达式中的某一部分时,过长的表达式可能使定位和更改变得麻烦,容易引入错误。| |**语法限制**|**1. **SQL Server对表达式的长度和复杂度有一定的限制。虽然没有直接的字符数限制,但如果表达式过于复杂,可能会超出某些内部缓冲区的大小限制,导致运行时错误。<br/>**2. **特别是在使用某些特定功能,如CASE WHEN语句或复杂的子查询时,过长的表达式可能超过系统能够有效处理的范围。| |**错误和异常处理**|**1. **长表达式中可能更容易出现语法错误或逻辑错误,调试和修复这类错误可能更加耗时。<br/>**2. **在表达式中使用动态SQL时,过长的字符串可能会增加SQL注入的风险,需要额外的预防措施来确保安全性。 为了避免这些问题,最佳实践是尽可能简化表达式,将复杂的逻辑分解成多个步骤,使用变量存储中间结果,或者将部分逻辑封装在存储过程中。这样不仅可以提高查询效率,还可以增强代码的可读性和可维护性。 ## 参考 > 微软: [表达式(Transact-SQL)](https://learn.microsoft.com/zh-cn/sql/t-sql/language-elements/expressions-transact-sql?view=sql-server-ver16) [CASE (Transact-SQL)](https://learn.microsoft.com/zh-cn/sql/t-sql/language-elements/case-transact-sql?view=sql-server-ver16) [COALESCE (Transact-SQL)](https://learn.microsoft.com/zh-cn/sql/t-sql/language-elements/coalesce-transact-sql?view=sql-server-ver16) [NULLIF (Transact-SQL)](https://learn.microsoft.com/zh-cn/sql/t-sql/language-elements/nullif-transact-sql?view=sql-server-ver16)
扫一扫手机看
点击排行
windows 文件资源管理器使用
Layui 弹窗open使用说明
SQL Server 中字符串函数使用
C# 使用QQ邮箱代理做邮件接收功能
SQL Server关于apply的两种形式cross apply 和 outer apply
ASP.NET MVC 模型的自定义验证
nvm安装及常用命令
SQL Server 中数据类型转换
SQL Server 中WITH AS短语的使用
IE浏览器下AJAX缓存问题导致数据不更新的解决办法
订阅号