T-SQL编程

    T-SQL(Transact-SQL)是一种 SQL 扩展语言,由微软实现,运行在 Ms SQL Server 平台上。T-SQL 主要用来和SQL Server 交流,而查询语句则主要用来告诉服务器该作什么。T-SQL 是标准 SQL 语言的扩展,天然也继承了其基本功能:DDL、DML,DCL,DQL。另外,T-SQL 扩展了标准 SQL 不具有的编程特性,好比:运算符、文本字符串处理、流程控制、存储过程、API,自定义函数等。html

 

  一  T-SQL是什么sql

    T-SQL 并无被做为一种编程语言设计。虽然 T-SQL 通过多年的发展,已经加入了很多编程语言的特性,但其仍然缺乏真正的编程语言所具有的能力和灵活性。数据库

    T-SQL 被设计的目的是实现数据的检索和操纵,虽然其具备必定的编程能力,但其性能不能被很好的获得保证,当你但愿把 T-SQL 当作编程语言使用时,你会不可避免的遇到性能问题,因此,在使用它时,请在内心牢记,T-SQL 是操纵数据集的,这才是它发挥真正做用的地方。编程

 

  二  编程特性服务器

 

    1,语法约束编程语言

    T-SQL 命令不区分大小写,但建议使用大写。语句不强制使用 ; 结束。ide

1 SELECT * FROM TableName --能够运行
2 SELECT * FROM TableName;--也能运行

    注意缩进和对象命名规范。正确的缩进能保证你的代码易于阅读和维护。T-SQL 容许使用字母、数字、下划线、@、#、$符号来建立你本身的标识符(如变量、表名、视图名等),但首字母不能是数字和 $ 符号,建议遵循大驼峰命名法则。函数

1 CREATE TABLE MyTable
2 (
3     M_Name VARCAHR(20) NOT NULL,
4     ......
5 )

    T-SQL 同时支持双引号和单引号,那么如何区分呢?双引号通常用来标识 T-SQL 对象,好比表、视图,过程等,还有一种表示对象的方式是 [] ,而单引号用来表示字符串数据。性能

1 SELECT "M".*  FROM  "MyTable" AS "M"
2   WHERE "M".Name='张三';
3 SELECT "M".*  FROM  [MyTable];

    T-SQL 使用 -- 双中横线表示单行注释,/* */ 表示多行注释。测试

1 /* 
2 这是多行注释
3 这是多行注释
4  */
5 --这是单行注释

      

    2,运算符

    数学运算符:+ 加、- 减、* 乘、/ 除、% 余。数学运算符返回值时数学计算值。= 既能够是等号也能够是赋值。+ 既能够做为数学加号也能够做为链接运算符。

    比较运算符:> 大于、< 小于、>= 大于或等于、<= 小于或等于、<> 不等于、!= 不等于、!< 不小于、!> 不大于,比较运算返回的是布尔值。

    逻辑运算符:AND、OR、NOT、BETWEEN、LIKE、IN。

      

    3,变量

    变量分为局部变量和全局变量。局部变量用户能够自定义,而全局变量由系统管理,用户可使用,但不能更改。 

    局部变量使用 DECLARE 关键字声明,以 @ 符号标识。使用 SELECT 或 SET 关键之赋值。

1 DECLARE @Age INT
2 DECLARE @Name VARCAHR(20)
3 SET @Age=20
4 SELECT @Name='张三'
5 PRINT @Name+@Age

    SET 一次只能为一个变量赋值,SELECT 一次能够为多个变量赋值。在 T-SQL 中,有两种方式输出内容,PRINT 和 SELECT。PRINT 一次只能输出一个值,一般用于向 API 返回值,而 SELECT 能够以数据集的形式返回多行记录。

    全局变量以 @@ 符号标识,经常使用的全局变量以下:

1 SELECT @@version AS '版本';--返回当前数据库的版本信息
2 SELECT @@error AS '错误ID';--返回上一次T-SQL的错误ID,若是正常执行了查询,error为0,出错时error必定大于0
3 SELECT @@identity AS '标示符';--返回最后一次的标识符,如先执行了
4 SELECT @@connections AS '链接次数';--返回自上次SQL启动以来链接或试图链接的次数
5 SELECT @@total_errors AS '错误总数';--返回至启动以来的错误总数
6 SELECT @@total_read AS '读取总数';--返回自启动以来的读取总数
7 SELECT @@total_write AS '写入总数';--返回自启动以来的写入总数
8  ......

 

    4,流程控制

    BEGIN...END:该语句用来标记一个语句块,一般和其余流程控制语句一块儿使用。

    IF...ELSE:条件判断语句。若是 IF 关键字后面的条件表达式计算结果为真,则执行语句块1,否者执行语句块2。IF 和 ELSE 之间还能够存在 ELSE IF 组合关键字,表示逻辑上的其余状况。

1 IF 条件
2     BEGIN
3     语句块1
4     END
5 ELSE
6     BEGIN
7     语句块2
8     END    

    若是语句块只有一条语句,那么BEGIN...END 能够省略。

    WHILE:循环。当 WHILE 关键字后面的循坏条件为真时,执行下面的语句块,须要注意的是,语句块中应该有可以左右循坏条件的语句存在,不然这将变成一个死循环。

1 WHILE 循环条件
2 BEGIN
3     语句块
4 END
5 --若是只有一条语句,也能够省略BEGIN...END

    BREAK 和 CONTINUE:退出循环。该关键字通常和循环配合使用,BREAK 用于结束整个循环,无论循环条件是否为真。CONTINUE 用于跳过本次循环须要执行的代码快,直接开始执行下一次须要执行的代码块(前提是循环条件还为真)。

    WAITFOR:延时执行。

 1 BEGIN
 2     WAITFOR TIME '22:00'
 3     语句块
 4 END
 5 --指定执行语句的具体时间
 6 BEGIN
 7     WAITFOR DELAY '01:00:00'
 8     语句块
 9 END
10 --指定执行语句的延迟时间量

    CASE:基于列的计算返回指定的值。CASE 执行的逻辑和 IF ELSE 语句相似,当 WHEN 关键字后面的表达式结果为真时,用 THEN 后面的新值替换列中原来的值。

1 CASE2     WHEN 表达式 THEN 新的值或表达式
3 WHEN 表达式 THEN 新的值或表达式
4 ...... 5 ELSE 其余未指定匹配值或表达式的新值 6 END

 

    三  函数

 

    1,聚合函数

    聚合函数主要包括:SUM() 求和,AVG() 求平均值,MIN() 求最小值,MAX() 求最大值,COUNT() 计数。

    以上聚合函数和标准 SQL 中的聚合函数功能同样,使用方式也同样,这里再也不介绍,若有疑问能够参照个人《SQL入门》

      

    2,日期函数

    T-SQL 提供了功能强大的操做日期类型值的相关函数,经过这些函数你能够轻松实现好比,解析日期类型值的日期与时间部分,比较与操纵日期/时间值等。

    A:GETDATE() 和 GETUTCDATE()     

1 SELECT GETDATE() AS '标准时间'
2 SELECT GETUTCDATE() AS 'UTC时间'

    GETUTCDATE() 经过本地服务器上的时区来求出 UTC 时间,通常使用前一个函数较多。

    B:DATEPART() 和 DATENAME()

    这两个函数的做用相似,都是用于返回日期中指定的部分,不通点在于:DATEPART() 返回值类型为 INT,而DATENAME() 为 NVARCHAR。

 1 DECLARE @MyDate;
 2 SET @MyDate=GETDATE();
 3 PRINT DATEPART(year,@mydate);--int
 4 PRINT DATENAME(year,@mydate);--nvarcahr
 5 PRINT DATEPART(month,@mydate);--int
 6 PRINT DATENAME(month,@mydate);--nvarcahr
 7 PRINT DATEPART(day,@mydate);--int
 8 PRINT DATENAME(day,@mydate);--nvarcahr
 9 PRINT DATEPART(dayofyear,@mydate);--int
10 PRINT DATENAME(dayofyear,@mydate);--nvarcahr
11 --可选的参数还有 week,weekday,hour,minute,second,millisecond等,请自行测试返回值

    C:YEAR(),MONTH(),DAY()

    以 INT 类型值返回指定日期的年,月,日。

1 SELECT YEAR(MyDate)AS YEAR,MONTH(MyDate)AS MONTH,DAY(MyDate)AS DAY

    D:DATEADD() 和 DATEDIFF()

    DATEADD() 用于计算给定时间间隔后的日期,DATEDIFF() 用于计算两个日期之间指定单位的时间差。

1 DECLARE @MyDate DATETIME;
2 DECLARE @DateAfter7Days DATETIME;
3 SET @MyDate=GETDATE();
4 SET @DateAfter7Days=DATEADD(day,7,@MyDate) ;--计算距今7天以后的日期
5 PRINT @DateAfter7Days;
6 PRINT DATEDIFF(day,@MyDate,@DateAfter7Days) ;--7,差7天
7 --第一个参数都是时间单位,可选的有:year,month,day,week,hour,minute,second等,DATEADD()的第二个参数是一个数字,能够为负,觉得以前的日期

 

    3,数学函数

    T-SQL 数学函数专门用于数学计算,经常使用的数学函数列表请移步《T-SQL 数学函数》,这里不举例说明。

      

    4,字符函数

 1 SELECT ASCII('ABC');--计算字符串第一个字符的ASCII值
 2 SELECT CHAR(65);--把给定ASCII编码转换成字符
 3 
 4 SELECT LOWER('AbC');--全转换为小写
 5 SELECT UPPER('aBc');--全转换为大写
 6 
 7 SELECT LTRIM('   AAA');--去掉左边的空格
 8 SELECT RTRIM('AAA   ');--去掉右边的空格
 9 
10 SELECT LEN('  ABC  ');--计算字符个数,不包含后面的空格
11 SELECT LEFT('ABCDEFG',3);--从左边返回指定个数的字符
12 SELECT RIGHT('ABCDEFG',3);--从右边返回指定个数的字符
13 SELECT SUBSTRING('ABCDEFG',3,2);--从第三个字符开始返回2个字符
14 
15 SELECT CHARINDEX('A', 'CCBBAA'); --返回第一个参数字符串在指定字符串中的位置 16 SELECT REPLACE('AABBCC','A','D'); --用第三个参数替换第一个参数中的第二个参数所指定字符串

 

    5,类型转换函数

    T-SQL 中的显示类型转换经过 CONVERT() 和 CAST() 实现。

1 SELECT CONVERT(INT,' 123 ');
2 SELECT CAST(' 123 ' AS INT);
3 --把字符串转换成数字,能够有空格,但不能有其余字符
4 
5 SELECT CONVERT(DATE,'2020-01-01');
6 SELECT CAST('2020-01-01' AS DATE);
7 --把字符串表示的日期转换为日期格式

    CONVERT() 另外一个很重要的应用是:以不一样的格式显示日期。这是你须要传入第三个参数,该参数用来指定格式日期:

1 SELECT CONVERT(VARCHAR(19),GETDATE());--04 27 2020 11:10AM
2 SELECT CONVERT(VARCHAR(10),GETDATE(),110); --04-27-2020
3 SELECT CONVERT(VARCHAR(11),GETDATE(),106);--27 04 2020
4 SELECT CONVERT(VARCHAR(24),GETDATE(),113);--27 04 2020 11:11:07:857

 

    6,排序

    ROW_NUMBER() OVER():经过在 OVER 中使用 ORDER BY 字句,对指定列排序,并生成一个标识该行的惟一序号(从1开始)。好比有如学生生源信息表 Person:

id name prov
1001 张一 四川
1002 张二 湖北
1003 张三 上海
1004 张四 北京
1005 张五 四川
1 SELECT ROW_NUMBER() OVER(ORDER BY ID) AS NUM,* FROM Person; --多了一列 NUM,值从1 - 4
1 SELECT ROW_NUMBER() OVER(PARTITION BY PROV ORDER BY ID) AS NUM,* FROM Person;
2 -- 先经过 prov 分组学生信息,而后再经过 id 对学生在组内排序,生成 num 列,张一的 num 为1,张五的 num 为 2,其余的均为1

    RANK() OVER():排序和 ROW_NUMBER() OVER() 类似,区别是它不能分组排序,而且它的排序结果可能会出现相同的序号,且总体可能会不连续。

    若是某些行的的值相同,那么 RANK() OVER() 会为这些行给出相同的序号,而且,下一行的排序并不会和上一个相邻。

    好比:前两个学生的成绩都是 100 分,那么他们应该是并列第一名,排序都是 1,第三名学生的成绩是 99,应该是第二名,但 RANK() OVER() 的排序会是 3 。

 

  四  编程对象

 

    1,视图

    设计视图的惟一目的就是简化代码,解决代码重用问题。

    视图是一个逻辑表,它和真正的表在使用上彻底一致,但他不是一个真正的表,视图的本质是一个复杂的查询语句。查询视图会返回数据,但这些数据并非存储在视图中。而是在具体的真实的表中。

    语法:

 1 CREATE VIEW VIEW_NAME
 2 AS
 3     语句
 4 --建立视图
 5 ALTER VIEW VIEW_NAME
 6 AS
 7     语句
 8 --修改视图
 9 DROP VIEW VIEW_NAME 
10 --删除视图

    建立视图时能够在视图名后使用()来为视图的列指定新的名称,但必须所有提供,不能只指定一部分列的新名称。

    虽然视图也能够用来对原始数据进行操做,但不建议这样作,由于使用视图简化查询才是它的本职工做。

    使用视图的一个注意点:不能直接使用 order by,若是须要排序,则必须配合 TOP 关键字一块儿使用。

    

    2,存储过程

    存储过程不只能够实现返回查询数据集的功能,并且功能比视图更进一步,它还提供了不少编程功能,好比:带参数的视图,返回标量值,维护记录,处理业务逻辑等等。

    一个存储过程实现了一个特定的功能,而且别SQL Server 编译好后存储在数据库中,下一次执行不须要从新编译,提升程序执行效率。

    先来看基本语法:

 1 CREATE PROCEDURE PROC_NAME
 2 AS
 3     语句
 4 --建立存储过程
 5 ALTER PROCEDURE PROC_NAME
 6 AS
 7     语句
 8 --修改存储过程
 9 DROP PROCDURE PROC_NAME
10 --删除存储过程
11 EXECUTE PROC_NAME
12 --执行存储过程

    A:带参数的存储过程

1 CREATE PROCEDURE Proc_name
2 @Var_name
3 AS
4     SELECT *  FROM Table_name
5         WHERE Some_col = @Var_name 
6 --在存储过程当中,使用变量过滤数据,变量不须要使用 declare 关键字
7 EXECUTE Proc_name Something;
8 EXECUTE Proc_name @Var_name=Something;
9 --两种传参的方式,多个参数使用逗号隔开

    B:返回值

    从存储过程返回值有两种方式,OUTPUT 修饰符和 RETURN 关键字。

    先来看 OUTPUT 方式:

 1 CREATE PROCEDURE P_TEST
 2 @OUT INT OUTPUT
 3 AS
 4     SET @OUT=1;
 5 GO
 6 DECLARE @NUM INT;
 7 EXECUTE P_TEST @NUM OUTPUT;
 8 SELECT @NUM;
 9 GO
10 --GO 表示一批 T-SQL 语句结束,GO 以后的 T-SQL 语句属于另外一个批处理的范围,GO 不是 T-SQL 命令,它只是一个能被 SQL Server 管理器识别的命令

    使用这种方式,在建立存储过程时,须要定义一个带有 OUTPUT 修饰符的参数,用于存储即将被返回的值。在存储过程的外部,也须要定义一个变量,用来接收返回的值。而且在执行存储过程时,须要把接收值的变量传递到存储过程当中去,且必须指明修饰符 OUTPUT,不然,存储过程虽然能正常执行,但不会返回任何数据。

    另外一种 RETURN 方式:

1 ALTER PROCEDURE P_TEST
2 AS
3     RETURN 1;
4 GO
5 DECLARE @NUM INT;
6 EXECUTE @NUM = P_TEST;
7 SELECT @NUM;
8 GO

    这种方式使用 RETURN 关键字显示的指定须要返回的值,但与 OUTPUT 不一样的是,它只能返回 INT类型的值。这种方式使用起来更简单,不准要定义额外的变量,只须要在外部定义一个接收数据的变量,并在执行时赋值,便可拿到存储过程的返回值。

    RETURN 还有一个功能:结束存储过程的执行。即执行完 RETURN 语句以后,后面的任何语句都不会再被执行了,存储过程的执行到此结束。

    

    3,自定义函数

    和存储过程很类似,用户自定义函数也是一组有序的T-SQL语句,用户自定义函数被预先优化和编译而且做为一个单元进行调用。它和存储过程的主要区别在于返回结果的方式。

    用户自定义函数能够传入参数,但传出参数被返回值概念替代了。用户自定义函数的返回值能够是普通的标量值,也能够是表。

1 CREATE FUNCTION FUN_NAME
2 ( 参数列表 )
3 RETURNS 数据类型
4 AS
5 BEGIN
6     语句块
7 END

    使用 CREATE FUNCTION 建立用户自定义函数,函数名后面用()定义传入的参数,而后使用 RETURNS 定义函数返回值的数据类型,用户自定义函数的语句块必须包含在 BEGIN...END中,而且在自定义函数内部,不能调用非肯定性的函数,好比 GETDATE()。这是由于若是在内部出现非肯定性函数,可能致使自定义函数在参数相同的状况下而返回值不一样。请看下面的例子:

1 CREATE FUNCTION GetAge
2 (@Birthday DATE,@Today DATE)
3 AS
4 BEGIN
5     RETURN DATEDIFF(DAY,@Birthday,@Today)/365
6 END
7 --根据提供的生日和如今的日期,计算年龄
8 SELECT DBO.GetAge('2000-01-01',GETDATE());

    一般状况下,SQL SERVER 把没指定全部者或模式的函数调用当作一个系统内置函数,因此在使用用户自定义函数时,请至少要指定全部者或模式名。

    若是要使用用户自定义函数返回表类型的值,你须要这样作:

 1 CREATE FUNCTION MYFUN(@VAR 数据类型)
 2 RETURNS TABLE
 3 AS
 4 BEGIN
 5     RETURN
 6     (
 7         SELECT * FROM TABLENAME WHERE 使用@VAR 的条件表达式;
 8     )
 9 END
10 
11 SELECT * FROM MYFUN(参数值);

    使用 SELECT * FROM 函数名这样的语法,那么这个函数基本和表具备同样的功能。

 

  五  其余

 

    1,游标

    游标本质上是一个包含多条记录的结果集,保存在内存中。在 T-SQL 中,声明一个游标类型的变量,你就能够对读入的结果集进行管理,对每条记录进行迭代了。因此,游标其实是一种能从包括多条数据记录的结果集中,每次提取一条记录的机制。

    游标基本用法:

 1 --1:建立游标
 2 DECLARE Cur_Name CURSOR
 3 FOR
 4     SELECT Col1,Col2 FROM Tbale_name
 5 DECLARE @Var_Name1,@Var_Name2
 6 --2:打开游标
 7 OPEN Cur_Name
 8 --3:检索与操做数据
 9 FETCH NEXT FROM Cur_Name INTO @Var _Name1,@Var_Name2
10 WHILE @@Fetch_Status=0
11 BEGIN
12     PRINT @Var _Name1+':'+@Var_Name2
13     FETCH NEXT FROM Cur_Name INTO @Var _Name1,@Var_Name2
14 END
15 --4:关闭游标
16 CLOSE Cur_Name
17 --5:释放游标
18 DEALLOCATE Cur_Name

    使用游标必要的五步:建立,打开,检索,关闭,释放。缺一不可。

    建立游标时,游标名和关键字 CURSOR 之间能够有可参数列表:INSENSITIVE,SCROLL,前者表示生成一个结果集的副本,而不是使用数据库的元数据。后者指定在数据检索时,全部的提取选项(FIRST(第一条记录)、LAST(最后一条记录)、PRIOR(上一条记录)、NEXT(下一条记录)、RELATIVE(相对当前移动 n 行的记录)、ABSOLUTE(第 n 记录))都可用。通常到了使用游标的时候,都是须要对每一条数据进行不一样的操做了,因此提取选项多数状况都是使用 NEXT。

    在查询语句以后,还能够经过 FOR 关键字指定哪些列可更新或者只读,语法规则:[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]

    游标的主要做用在于,容许程序对由查询语句 SELECT 返回的行集合中的每一行执行相同或不一样的操做,而不是对整个行集合执行同一个操做,而且它还提供对基于游标位置而对表中数据进行删除或更新的能力。

    使用游标虽然能够带来必定程度的灵活性,但它是以牺牲性能和效率为代价的,因此游标通常做为最后的开发选项,毕竟,即便不对数据作任何特殊操做,也须要必要的五个步骤。

    

    2,触发器

    触发器其实是一类特殊的存储过程,它能被 DDL 和 DML 触发,并自动运行,不能被用户显式的触发。

    若是咱们为表或视图的某些操做设置触发器后,那么,当咱们在数据库中针对这些表或视图执行这些操做时,触发器内的程序代码将被执行。

    基本语法(DML触发器):

1 CREATE TRIGGER 触发器名称
2 ON 表或视图
3 触发器类型(FOR|AFTER|INSTEAD OF4 操做类型(INSERTUPDATEDELETE5 AS
6     语句块

    基本语法(DDL触发器):

1 CREATE TRIGGER 触发器名称
2 ONALL SERVER|DATEBASE)
3 触发器类型(FOR|AFTER)
4 操做类型(CREATEALTERDROP...5 AS
6     语句块

    触发器类型 FOR 和 AFTER 都是指在操做成功后执行,区别是 AFTER 类型只支持表,而不支持视图。

    INSTEAD OF 触发器使用触发器内部的操做替代指定的操做类型,真正起做用的是触发器里面的动做!

    

    3,其余的

    A:MERGE

    MERGE 命令的做用是根据与源表的联接结果在目标表上运行插入,更新或删除操做。好比,经过对比另外一个表的差别,在一个表中插入、更新或删除数据,以保证两个表中的数据同步。

    一个简单的示例:

 1 MERGE INTO Target
 2  --这里是目标表,它将要被源表Merge
 3 USING Source
 4 --这里是源表
 5 ON 匹配条件
 6     WHEN MATCHED
 7 --匹配条件为真的记录,执行下面的then
 8         THEN UPDATE --执行更新操做 
 9     WHEN NOT MATCHED BY TARGET
10 --目标表中不存在,而源表中存在数据,执行下面的then
11         THEN INSERT--执行插入操做
12     WHEN NOT MATCHED BY SOURCE
13 --当目标表中存在,而源表中不存在数据执,执行下面then
14         THEN DELETE--执行删除操做

    MERGE 命令在许多时候均可以替代游标批量操做数据,下一次你在考虑使用游标时,不妨先想想,可否用 MERGE 代替呢!

    B:临时表和表变量

    临时表与永久表类似,只是它的建立是在 Tempdb 中,它只有在一个数据库链接结束后或者由SQL命令DROP掉,才会消失,不然就会一直存在。

    临时表分为本地和全局两种,本地临时表的名称都是以“#”为前缀,只有在本地当前的用户链接中才是可见的,当用户从实例断开链接时被删除。全局临时表的名称都是以“##”为前缀,建立后对任何用户都是可见的,当全部引用该表的用户断开链接时被删除。

 1 --建立临时表
 2 --方式一
 3 CREATE TABLE #表名()
 4 CREATE TABLE ##表名()
 5 --方式二
 6 SELECT INTO #表名 FROM TABLE
 7 SELECT INTO ##表名 FROM TABLE
 8 --查询和删除
 9 SELECT * FROM #表名
10 DROP * FROM #表名

    临时表还能够和普通表同样添加索引,主键、外键和约束。

    表变量本质上仍是变量,因此依然使用 DECLARE 关键字声明,既然是变量,那么也分为本地及全局的两种,本地表变量的名称都是以“@”为前缀,只有在本地当前的用户链接中才能够访问。全局表变量的名称都是以“@@”为前缀,和其余的系统全局变量同样。

1 DECLARE @News TABLE()

    对于表变量,能够正常执行 DML。表变量通常存储在内存中,而且不能添加索引和约束。

    不少时候表变量和临时表的功能是重合的,如何选取彻底取决于应用对内存的压力,若是数据量比较大,可使用临时表,不然推荐使用表变量。

    C:CTE

    共用表表达式 CTE ,你能够把它理解为一个临时的查询结果集,你能够在接下来的 SELECT、INSERT、UPDATE等语句中重复引用它。微软对其的用处评价颇高,说来惭愧,我在实际工做中,主要是为了在复杂子查询中减小代码冗余和便于维护而使用它。

1 WITH CTEName (col1,col2)
2 AS
3 (
4     SELECT col1,col2 FROM TableName
5 )

    注意,定义的 CTE 只能在紧接着的语句中使用。

    D:EXISTS()

    EXISTS 用于检测是否有符合条件的数据存在,它是一种探测机制,它执行时不关注有多少符合条件的记录,只关注是否存在这样的记录。因此,多数时候可使用 EXISTS 子查询替换 IN 以提升性能。与之相对是 NOT EXISTS(),用于判断是否不存在。

1 SELECT * FROM TableA A
2 WHERE EXISTS
3 (SELECT * FROM TableB B WHERE A.ID = B.ID )
4 --查询A表中那些ID和B表相同的数据
相关文章
相关标签/搜索