2010-10-16

内连接 外连接 区别 sql



你是要弄清楚区别在什么地方还是单纯想要文字说明 
文字说明的楼上说了一大堆了,不说了。 
弄个例题,直观一点。两个表: 
--表stu 
id name 
1, Jack 
2, Tom 
3, Kity 
4, nono 
--表exam 
id grade 
1, 56 
2, 76 
11, 89 

内连接 (显示两表id匹配的) 
select stu.id,exam.id,stu.name, exam.grade from stu inner join exam on stu.id=exam.id 

-------------------------------- 
1 1 Jack 56 
2 2 Tom 76 


左连接(显示join 左边的表的所有数据,exam只有两条记录,所以stu.id,grade 都用NULL 显示) 
select stu.id,exam.id,stu.name, exam.grade from stu left join exam on stu.id=exam.id 
1 1 Jack 56 
2 2 Tom 76 
3 NULL Kity NULL 
4 NULL nono NULL 

右连接(与作连接相反,显示join右边表的所有数据) 
select stu.id,exam.id,stu.name, exam.grade from stu right join exam on stu.id=exam.id 
1 1 Jack 56 
2 2 Tom 76 
NULL 11 NULL 89 
  
  
内连接取交集,外连接分左和右, 
左连接左边的全取, 
右连接右边的全取 

--
we drink green tea

SQL 左外连接,右外连接,全连接,内连接 四种连接的差异

SQL 左外连接,右外连接,全连接,内连接 四种连接的差异

外联接。外联接可以是左向外联接、右向外联接或完整外部联接。     
   在    FROM    子句中指定外联接时,可以由下列几组关键字中的一组指定:   
    
   LEFT    JOIN    或    LEFT    OUTER    JOIN。     
   左向外联接的结果集包括    LEFT    OUTER    子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。   
    
   RIGHT    JOIN    或    RIGHT    OUTER    JOIN。     
   右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。   
    
   FULL    JOIN    或    FULL    OUTER    JOIN。     
   完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。   
    
   仅当至少有一个同属于两表的行符合联接条件时,内联接才返回行。内联接消除与另一个表中的任何行不匹配的行。而外联接会返回    FROM    子句中提到的至少一个表或视图的所有行,只要这些行符合任何    WHERE    或    HAVING    搜索条件。将检索通过左向外联接引用的左表的所有行,以及通过右向外联接引用的右表的所有行。完整外部联接中两个表的所有行都将返回。   
    
   Microsoft®    SQL    Server™    2000    对在    FROM    子句中指定的外联接使用以下    SQL-92    关键字:     
    
   LEFT    OUTER    JOIN    或    LEFT    JOIN   
    
    
   RIGHT    OUTER    JOIN    或    RIGHT    JOIN   
    
    
   FULL    OUTER    JOIN    或    FULL    JOIN     
   SQL    Server    支持    SQL-92    外联接语法,以及在    WHERE    子句中使用    *=    和    =*    运算符指定外联接的旧式语法。由于    SQL-92    语法不容易产生歧义,而旧式    Transact-SQL    外联接有时会产生歧义,因此建议使用    SQL-92    语法。   
    
   使用左向外联接   
   假设在    city    列上联接    authors    表和    publishers    表。结果只显示在出版商所在城市居住的作者(本例中为    Abraham    Bennet    和    Cheryl    Carson)。   
    
   若要在结果中包括所有的作者,而不管出版商是否住在同一个城市,请使用    SQL-92    左向外联接。下面是    Transact-SQL    左向外联接的查询和结果:   
    
   USE    pubs   
   SELECT    a.au_fname,    a.au_lname,    p.pub_name   
   FROM    authors    a    LEFT    OUTER    JOIN    publishers    p   
   ON    a.city    =    p.city   
   ORDER    BY    p.pub_name    ASC,    a.au_lname    ASC,    a.au_fname    ASC   
    
   下面是结果集:   
    
   au_fname    au_lname    pub_name     
   --------------------    ------------------------------    -----------------     
   Reginald    Blotchet-Halls    NULL   
   Michel    DeFrance    NULL   
   Innes    del    Castillo    NULL   
   Ann    Dull    NULL   
   Marjorie    Green    NULL   
   Morningstar    Greene    NULL   
   Burt    Gringlesby    NULL   
   Sheryl    Hunter    NULL   
   Livia    Karsen    NULL   
   Charlene    Locksley    NULL   
   Stearns    MacFeather    NULL   
   Heather    McBadden    NULL   
   Michael    O'Leary    NULL   
   Sylvia    Panteley    NULL   
   Albert    Ringer    NULL   
   Anne    Ringer    NULL   
   Meander    Smith    NULL   
   Dean    Straight    NULL   
   Dirk    Stringer    NULL   
   Johnson    White    NULL   
   Akiko    Yokomoto    NULL   
   Abraham    Bennet    Algodata    Infosystems   
   Cheryl    Carson    Algodata    Infosystems   
    
   (23    row(s)    affected)   
    
   不管是否与    publishers    表中的    city    列匹配,LEFT    OUTER    JOIN    均会在结果中包含    authors    表的所有行。注意:结果中所列的大多数作者都没有相匹配的数据,因此,这些行的    pub_name    列包含空值。   
    
   使用右向外联接   
   假设在    city    列上联接    authors    表和    publishers    表。结果只显示在出版商所在城市居住的作者(本例中为    Abraham    Bennet    和    Cheryl    Carson)。SQL-92    右向外联接运算符    RIGHT    OUTER    JOIN    指明:不管第一个表中是否有匹配的数据,结果将包含第二个表中的所有行。   
    
   若要在结果中包括所有的出版商,而不管城市中是否还有出版商居住,请使用    SQL-92    右向外联接。下面是    Transact-SQL    右向外联接的查询和结果:   
    
   USE    pubs   
   SELECT    a.au_fname,    a.au_lname,    p.pub_name   
   FROM    authors    AS    a    RIGHT    OUTER    JOIN    publishers    AS    p   
   ON    a.city    =    p.city   
   ORDER    BY    p.pub_name    ASC,    a.au_lname    ASC,    a.au_fname    ASC   
    
   下面是结果集:   
    
   au_fname    au_lname    pub_name     
   --------------------    ------------------------    --------------------     
   Abraham    Bennet    Algodata    Infosystems   
   Cheryl    Carson    Algodata    Infosystems   
   NULL    NULL    Binnet    &    Hardley   
   NULL    NULL    Five    Lakes    Publishing   
   NULL    NULL    GGG&G   
   NULL    NULL    Lucerne    Publishing   
   NULL    NULL    New    Moon    Books   
   NULL    NULL    Ramona    Publishers   
   NULL    NULL    Scootney    Books   
    
   (9    row(s)    affected)   
    
   使用谓词(如将联接与常量比较)可以进一步限制外联接。下例包含相同的右向外联接,但消除销售量低于    50    本的书籍的书名:   
    
   USE    pubs   
   SELECT    s.stor_id,    s.qty,    t.title   
   FROM    sales    s    RIGHT    OUTER    JOIN    titles    t   
   ON    s.title_id    =    t.title_id   
   AND    s.qty    >    50   
   ORDER    BY    s.stor_id    ASC   
    
   下面是结果集:   
    
   stor_id    qty    title     
   -------    ------    ---------------------------------------------------------     
   (null)    (null)    But    Is    It    User    Friendly?     
   (null)    (null)    Computer    Phobic    AND    Non-Phobic    Individuals:    Behavior     
   Variations     
   (null)    (null)    Cooking    with    Computers:    Surreptitious    Balance    Sheets     
   (null)    (null)    Emotional    Security:    A    New    Algorithm     
   (null)    (null)    Fifty    Years    in    Buckingham    Palace    Kitchens     
   7066    75    Is    Anger    the    Enemy?     
   (null)    (null)    Life    Without    Fear     
   (null)    (null)    Net    Etiquette     
   (null)    (null)    Onions,    Leeks,    and    Garlic:    Cooking    Secrets    of    the     
   Mediterranean     
   (null)    (null)    Prolonged    Data    Deprivation:    Four    Case    Studies     
   (null)    (null)    Secrets    of    Silicon    Valley     
   (null)    (null)    Silicon    Valley    Gastronomic    Treats     
   (null)    (null)    Straight    Talk    About    Computers     
   (null)    (null)    Sushi,    Anyone?     
   (null)    (null)    The    Busy    Executive's    Database    Guide     
   (null)    (null)    The    Gourmet    Microwave     
   (null)    (null)    The    Psychology    of    Computer    Cooking     
   (null)    (null)    You    Can    Combat    Computer    Stress!     
    
   (18    row(s)    affected)   
    
   有关谓词的更多信息,请参见    WHERE。     
    
   使用完整外部联接   
   若要通过在联接结果中包括不匹配的行保留不匹配信息,请使用完整外部联接。Microsoft®    SQL    Server™    2000    提供完整外部联接运算符    FULL    OUTER    JOIN,不管另一个表是否有匹配的值,此运算符都包括两个表中的所有行。   
    
   假设在    city    列上联接    authors    表和    publishers    表。结果只显示在出版商所在城市居住的作者(本例中为    Abraham    Bennet    和    Cheryl    Carson)。SQL-92    FULL    OUTER    JOIN    运算符指明:不管表中是否有匹配的数据,结果将包括两个表中的所有行。   
    
   若要在结果中包括所有作者和出版商,而不管城市中是否有出版商或者出版商是否住在同一个城市,请使用完整外部联接。下面是    Transact-SQL    完整外部联接的查询和结果:   
    
   USE    pubs   
   SELECT    a.au_fname,    a.au_lname,    p.pub_name   
   FROM    authors    a    FULL    OUTER    JOIN    publishers    p   
   ON    a.city    =    p.city   
   ORDER    BY    p.pub_name    ASC,    a.au_lname    ASC,    a.au_fname    ASC   
    
   下面是结果集:   
    
   au_fname    au_lname    pub_name     
   --------------------    ----------------------------    --------------------     
   Reginald    Blotchet-Halls    NULL   
   Michel    DeFrance    NULL   
   Innes    del    Castillo    NULL   
   Ann    Dull    NULL   
   Marjorie    Green    NULL   
   Morningstar    Greene    NULL   
   Burt    Gringlesby    NULL   
   Sheryl    Hunter    NULL   
   Livia    Karsen    NULL   
   Charlene    Locksley    NULL   
   Stearns    MacFeather    NULL   
   Heather    McBadden    NULL   
   Michael    O'Leary    NULL   
   Sylvia    Panteley    NULL   
   Albert    Ringer    NULL   
   Anne    Ringer    NULL   
   Meander    Smith    NULL   
   Dean    Straight    NULL   
   Dirk    Stringer    NULL   
   Johnson    White    NULL   
   Akiko    Yokomoto    NULL   
   Abraham    Bennet    Algodata    Infosystems   
   Cheryl    Carson    Algodata    Infosystems   
   NULL    NULL    Binnet    &    Hardley   
   NULL    NULL    Five    Lakes    Publishing   
   NULL    NULL    GGG&G   
   NULL    NULL    Lucerne    Publishing   
   NULL    NULL    New    Moon    Books   
   NULL    NULL    Ramona    Publishers   
   NULL    NULL    Scootney    Books

 

联接条件可在    FROM    或    WHERE    子句中指定,建议在    FROM    子句中指定联接条件。WHERE    和    HAVING    子句也可以包含搜索条件,以进一步筛选联接条件所选的行。   
    
   联接可分为以下几类:     
    
   内联接(典型的联接运算,使用像    =    或    <>    之类的比较运算符)。包括相等联接和自然联接。     
   内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。例如,检索    students    和    courses    表中学生标识号相同的所有行。   
    
   外联接。外联接可以是左向外联接、右向外联接或完整外部联接。     
   在    FROM    子句中指定外联接时,可以由下列几组关键字中的一组指定:   
    
   LEFT    JOIN    或    LEFT    OUTER    JOIN。     
   左向外联接的结果集包括    LEFT    OUTER    子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。   
    
   RIGHT    JOIN    或    RIGHT    OUTER    JOIN。     
   右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。   
    
   FULL    JOIN    或    FULL    OUTER    JOIN。     
   完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。   
    
   交叉联接。     
   交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。交叉联接也称作笛卡尔积。   
    
   例如,下面的内联接检索与某个出版商居住在相同州和城市的作者:   
    
   USE    pubs   
   SELECT    a.au_fname,    a.au_lname,    p.pub_name   
   FROM    authors    AS    a    INNER    JOIN    publishers    AS    p   
         ON    a.city    =    p.city   
         AND    a.state    =    p.state   
   ORDER    BY    a.au_lname    ASC,    a.au_fname    ASC   
    
   FROM    子句中的表或视图可通过内联接或完整外部联接按任意顺序指定;但是,用左或右向外联接指定表或视图时,表或视图的顺序很重要。有关使用左或右向外联接排列表的更多信息,请参见使用外联接。   


--
we drink green tea

SQL测试-------交集、并集、差集、笛卡尔积

并集:

使用 UNION 运算符组合多个结果
SELECT name,num FROM Table1
UNION
SELECT name,num FROM Table2

注意:查询的字段个数必须相同,Table2的字段类型要跟Table1的相同.
如果使用 UNION 运算符,那么单独的 SELECT 语句不能包含其自己的 ORDER BY 或 COMPUTE 子句。只能在最后一个 SELECT 语句的后面使用一个 ORDER BY 或 COMPUTE 子句;该子句适用于最终的组合结果集。GROUP BY 和 HAVING 子句只能在单独的 SELECT 语句中指定。

只用UNION有重复记录只取一条,用UNION ALL 时取所有重复记录

FULLl JOIN是表示并集
SELECT * FROM Table1 FULLl JOIN Table2 ON table1.id=table2.id

交集:

SELECT * FROM table1 AS a JOIN table2 AS b ON a.name =b.name

差集:

NOT IN 表示差集
SELECT * FROM table1 WHERE name NOT IN (SELECT name FROM table2)


笛卡尔积:

SELECT * FROM table1 CROSS JOIN table2 
没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。
不过,如果添加一个 WHERE 子句,则交叉联接的作用将同内联接一样。
注意:不能使用ON 关键字,只能用WHERE条件

union 和join不一样,union这个运算子是将资料列合并,而join是将栏位合并(我前面所讲)!
如果从栏位合并来讲,full join 算是并集,inner join 算是交集!left join 或right join 不完全是差集,也包括交集的结果,具体你的语句的查询结果如何还是要看实际的语句,就如cross join,加上where就变成inner join,前后的结果相差甚远


--
we drink green tea

SQL UNION 和 UNION ALL 用法详解

SQL UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。
同时,每条 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法

SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2

注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法

SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2

另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。

下面的例子中使用的原始表:
Employees_China:

E_ID E_Name 
01 Zhang, Hua 
02 Wang, Wei 
03 Carter, Thomas 
04 Yang, Ming

Employees_USA:
E_ID E_Name 
01 Adams, John 
02 Bush, George 
03 Carter, Thomas 
04 Gates, Bill

使用 UNION 命令
实例
列出所有在中国和美国的不同的雇员名:

SELECT E_Name FROM Employees_China
UNION
SELECT E_Name FROM Employees_USA

结果
E_Name 
Zhang, Hua 
Wang, Wei 
Carter, Thomas 
Yang, Ming 
Adams, John 
Bush, George 
Gates, Bill

注释:这个命令无法列出在中国和美国的所有雇员。在上面的例子中,我们有两个名字相同的雇员,他们当中只有一个人被列出来了。UNION 命令只会选取不同的值。

 ==================

在使用UNION处理查询时,有几个要点:

  1、所有要进行UNION的查询,其SELECT列表中列的数量必须相同。如果第一个查询的列表中有3个列,那么第二个查询(以及所有进行UNION的后续查询)的SELECT列表也必须是3个列。

  2、为合并的结果集返回的标头仅取自第一个查询。如果第一个查询的SELECT列表类似这样,SELECT Col1,Col2

  AS Second,Col3 FROM...,那么无论后续的查询中列的名称或别名如何,UNION返回的列标头都将分别是Col1、Second以及Col3。

  3、一个查询中每一列的数据类型必须与其他查询中相同对应的列的数据类型隐式兼容。注意:这里并不是一定要相同----它们只要能隐式转换即可。如果第一个查询中第二列的数据类型是char(20),那么第二个查询中第二列的数据类型是varchar(30)是可以的。然而,由于一切都是基于第一个查询,因此结果集中第二列所有长度超过20的行将被截断。

  4、与非UNION的查询不同,UNION的默认返回方式是DISTINCT而非ALL。在其他的查询中,所有行都将被返回,无论它们是否与别的行有重复,而UNION却不是这样的。除非在查询中使用了ALL关键字,否则只返回一个有重复的行。

 


--
we drink green tea

sql group by 详解

分组查询<Group by子句>

   select 字段名列表 from 表名 [where 条件表达式] group by 字段名
   select 字段名列表 from 表名 [where 条件表达式] group by 字段名 Having <筛选表达式>
   select cno,avg(degree) as chengji from score group by cno
   select cno,avg(degree) as chengji from score group by cno Having avg(degree)>80

   <字段名列表中包含聚合函数时,则计算每组的汇总值。

   如果使用Group by子句,字段名列表中任一非聚合表达式内的所有列都必需包含在 Group by列表中,或者Group by表达式必须与选择列表表达式完全匹配。>   筛选查询<Having子句>   <Having子句对Group by子句分组后的结果进行筛选,看其是否满足条件。 故此Having只能配合group by子句使用。>

   当Where子句,Group by子句,Having子句同时使用时,其顺序如下:

①执行Where子句,从表中选取行;
②由Group By分组;
③执行Having子句选取满足的分组条件。

   聚合函数:使用聚合函数,实现数据统计。
AVG:计算平均数
Count(*):统计查询输出的记录总数
Count():统计指定列中选择的记录总数
Max:最大值
Min:最小值
Sum:计算总和
Stdev:计算统计标准偏差
Var:统计方差


--
we drink green tea

compute 详解 sql 字句


    Select 字段名列表 From 表名 [where 条件表达式] Compute 汇总表达式
    Select cno,sno,degree From score Compute avg(degree)
    <compute子句生成的汇总结果附加在结果集的后面,汇总表达式须用到聚合函数>

(2).compute by:
    Select 字段名列表 frm 表名 
    [where 条件表达式] order by 字段名 compute 汇总表达式 by 分类字段名
    Select sno,cno,degree From sclass Order by cno compute Avg(degree) by cno
    Select sno,cno,degree From score Order by cno Asc,degree Desc
    compute avg(degree) by cno
    <compute by子句根据by后的字段名进行分组,必须与order by子句一起使用,分类字段名必须与order by后的字段名一致。>

--
we drink green tea

sql like 详解

3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、
varchar、text、ntext、datetime和smalldatetime等类型查询。
可使用以下通配字符:
百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。
下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。
方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。
[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
例如:
限制以Publishing结尾,使用LIKE '%Publishing'
限制以A开头:LIKE '[A]%'
限制以A开头外:LIKE '[^A]%'

LIKE

确定给定的字符串是否与指定的模式匹配。模式可以包含常规字符和通配符字符。模式匹配过程中,常规字符必须与字符串中指定的字符完全匹配。然而,可使用字符串的任意片段匹配通配符。与使用 = 和 != 字符串比较运算符相比,使用通配符可使 LIKE 运算符更加灵活。如果任何参数都不属于字符串数据类型,Microsoft® SQL Server" 会将其转换成字符串数据类型(如果可能)。

语法

match_expression [ NOT ] LIKE pattern [ ESCAPE escape_character ]

参数

match_expression

任何字符串数据类型的有效 SQL Server 表达式。

pattern

match_expression 中的搜索模式,可以包含下列有效 SQL Server 通配符。

通配符 描述 示例

% 包含零个或更多字符的任意字符串。 WHERE title LIKE '%computer%' 将查找处于书名任意位置的包含单词 computer 的所有书名。

_(下划线) 任何单个字符。 WHERE au_fname LIKE '_ean' 将查找以 ean 结尾的所有 4 个字母的名字(Dean、Sean 等)。

[ ] 指定范围 ([a-f]) 或集合 ([abcdef]) 中的任何单个字符。 WHERE au_lname LIKE '[C-P]arsen' 将查找以arsen 结尾且以介于 C 与 P 之间的任何单个字符开始的作者姓氏,例如,Carsen、Larsen、Karsen 等。

[^] 不属于指定范围 ([a-f]) 或集合 ([abcdef]) 的任何单个字符。 WHERE au_lname LIKE 'de[^l]%' 将查找以 de 开始且其后的字母不为 l 的所有作者的姓氏。

escape_character

字符串数据类型分类中的所有数据类型的任何有效 SQL Server 表达式。escape_character 没有默认值,且必须仅包含一个字符。

结果类型

Boolean

结果值

如果 match_expression 匹配指定模式,LIKE 将返回 TRUE。

注释

当使用 LIKE 进行字符串比较时,模式字符串中的所有字符都有意义,包括起始或尾随空格。如果查询中的比较要返回包含"abc "(abc 后有一个空格)的所有行,则将不会返回包含"abc"(abc 后没有空格)的列所在行。但是可以忽略模式所要匹配的表达式中的尾随空格。如果查询中的比较要返回包含"abc"(abc 后没有空格)的所有行,则将返回以"abc"开始且具有零个或多个尾随空格的所有行。

由于数据存储方式的原因,使用包含 char 和 varchar 数据模式的字符串比较可能无法通过 LIKE 比较。了解每种数据类型的存储方式以及导致 LIKE 比较失败的原因十分重要。下面的示例将局部 char 变量传递给存储过程,然后使用模式匹配查找某个作者的所有著作。在此过程中,作者的姓将作为变量传递。

CREATE PROCEDURE find_books @AU_LNAME char(20)

AS

SELECT @AU_LNAME = RTRIM(@AU_LNAME) + '%'

SELECT t.title_id, t.title

FROM authors a, titleauthor ta, titles t

WHERE a.au_id = ta.au_id AND ta.title_id = t.title_id

AND a.au_lname LIKE @AU_LNAME

当名字中包含的字符数小于 20 时,char 变量 (@AU_LNAME) 将包含尾随空格,这导致 find_books 过程中没有行返回。由于 au_lname 列为 varchar 类型,所以没有尾随空格。因为尾随空格是有意义的,所以此过程失败。

但下面的示例是成功的,因为尾随空格没有被添加到 varchar 变量中:

USE pubs

GO

CREATE PROCEDURE find_books2 @au_lname varchar(20)

AS

SELECT t.title_id, t.title

FROM authors a, titleauthor ta, titles t

WHERE a.au_id = ta.au_id AND ta.title_id = t.title_id

AND a.au_lname LIKE @au_lname + '%'

EXEC find_books2 'ring'

下面是结果集:

title_id title

-------- ---------------------------------------------------------------

MC3021 The Gourmet Microwave

PS2091 Is Anger the Enemy?

PS2091 Is Anger the Enemy?

PS2106 Life Without Fear

(4 row(s) affected)

使用 LIKE 的模式匹配

当搜索 datetime 值时,推荐使用 LIKE,因为 datetime 项可能包含各种日期部分。例如,如果将值 19981231 9:20 插入到名为 arrival_time 的列中,则子句 WHERE arrival_time = 9:20 将无法找到 9:20 字符串的精确匹配,因为 SQL Server 将其转换为 1900 年 1 月 1 日上午 9:20。然而,子句 WHERE arrival_time LIKE '%9:20%' 将找到匹配。

LIKE 支持 ASCII 模式匹配和 Unicode 模式匹配。当所有参数,包括 match_expression、pattern 和 escape_character(如果有)都是 ASCII 字符数据类型时,将执行 ASCII 模式匹配。如果其中任何参数属于 Unicode 数据类型,则所有参数将被转换为 Unicode 并执行 Unicode 模式匹配。当对 Unicode 数据(nchar 或 nvarchar 数据类型)使用 LIKE 时,尾随空格是有意义的。但是对于非 Unicode 数据,尾随空格没有意义。Unicode LIKE 与 SQL-92 标准兼容。ASCII LIKE 与 SQL Server 的早期版本兼容。

下面的一系列示例显示 ASCII LIKE 模式匹配与 Unicode LIKE 模式匹配所返回的行之间的差异:

-- ASCII pattern matching with char column

CREATE TABLE t (col1 char(30))

INSERT INTO t VALUES ('Robert King')

SELECT *

FROM t

WHERE col1 LIKE '% King' -- returns 1 row

-- Unicode pattern matching with nchar column

CREATE TABLE t (col1 nchar(30))

INSERT INTO t VALUES ('Robert King')

SELECT *

FROM t

WHERE col1 LIKE '% King' -- no rows returned

-- Unicode pattern matching with nchar column and RTRIM

CREATE TABLE t (col1 nchar (30))

INSERT INTO t VALUES ('Robert King')

SELECT *

FROM t

WHERE RTRIM(col1) LIKE '% King' -- returns 1 row

说明 如果使用 LIKE 进行字符串比较,模式字符串中的所有字符都有意义,包括起始空格或尾随空格。

使用 % 通配符

如果指定 LIKE '5%',SQL Server 将搜索后面带有零个或多个任意字符的数字 5。

例如,此查询将显示数据库中所有的系统表,因为它们都以字母 sys 开始:

SELECT TABLE_NAME

FROM INFORMATION_SCHEMA.TABLES

WHERE TABLE_NAME LIKE 'sys%'

说明请注意:系统表可以随版本不同而更改。推荐使用信息架构视图或适用的存储过程处理 SQL Server 系统表。

若要查阅非系统表的所有对象,请使用 NOT LIKE 'sys%'。如果共有 32 个对象且 LIKE 找到 13 个与模式匹配的名称,则 NOT LIKE 将找到 19 个与 LIKE 模式不匹配的对象。

使用 LIKE '[^s][^y][^s]%' 模式不一定每次找到的名称都相同。可能仅得到 14 个名称(而不是 19 个),除了系统表名称外,所有以 s 开始或第二个字母为 y 或第三个字母为 s 的名称也都将从结果中消除。这是因为用反向通配符匹配字符串是分步骤进行计算的,一次一个通配符。如果在计算过程中任一环节匹配失败,那么就会将其消除。

将通配符作为文字使用

可以将通配符模式匹配字符串用作文字字符串,方法是将通配符放在括号中。下表显示了使用 LIKE 关键字和 [ ] 通配符的示例。

符号 含义

LIKE '5[%]' 5%

LIKE '[_]n' _n

LIKE '[a-cdf]' a、b、c、d 或 f

LIKE '[-acdf]' -、a、c、d 或 f

LIKE '[ [ ]' [

LIKE ']' ]

LIKE 'abc[_]d%' abc_d 和 abc_de

LIKE 'abc[def]' abcd、abce 和 abcf

使用 ESCAPE 子句的模式匹配

可搜索包含一个或多个特殊通配符的字符串。例如,customers 数据库中的 discounts 表可能存储含百分号 (%) 的折扣值。若要搜索作为字符而不是通配符的百分号,必须提供 ESCAPE 关键字和转义符。例如,一个样本数据库包含名为 comment 的列,该列含文本 30%。若要搜索在 comment 列中的任何位置包含字符串 30% 的任何行,请指定由 WHERE comment LIKE '%30!%%' ESCAPE '!' 组成的 WHERE 子句。如果不指定 ESCAPE 和转义符,SQL Server 将返回所有含字符串 30 的行。

下例说明如何在 pubs 数据库 titles 表的 notes 列中搜索字符串"50% off when 100 or more copies are purchased":

USE pubs

GO

SELECT notes

FROM titles

WHERE notes LIKE '50%% off when 100 or more copies are purchased'

ESCAPE '%'

GO

示例

A. 使用带 % 通配符的 LIKE

下例查找 authors 表中所有区号为 415 的电话号码。

USE pubs

GO

SELECT phone

FROM authors

WHERE phone LIKE '415%'

ORDER by au_lname

GO

下面是结果集:

phone

------------

415 658-9932

415 548-7723

415 836-7128

415 986-7020

415 836-7128

415 534-9219

415 585-4620

415 354-7128

415 834-2919

415 843-2991

415 935-4228

(11 row(s) affected)

B. 使用带 % 通配符的 NOT LIKE

下例查找 authors 表中所有区号不是 415 的电话号码。

USE pubs

GO

SELECT phone

FROM authors

WHERE phone NOT LIKE '415%'

ORDER BY au_lname

GO

下面是结果集:

phone

------------

503 745-6402

219 547-9982

615 996-8275

615 297-2723

707 938-6445

707 448-4982

408 286-2428

301 946-8853

801 826-0752

801 826-0752

913 843-0462

408 496-7223

(12 row(s) affected)

C. 使用 ESCAPE 子句

下例使用 ESCAPE 子句和转义符查找 mytbl2 表的 c1 列中的精确字符串 10-15%。

USE pubs

GO

IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

WHERE TABLE_NAME = 'mytbl2')

DROP TABLE mytbl2

GO

USE pubs

GO

CREATE TABLE mytbl2

(

c1 sysname

)

GO

INSERT mytbl2 VALUES ('Discount is 10-15% off')

INSERT mytbl2 VALUES ('Discount is .10-.15 off')

GO

SELECT c1

FROM mytbl2

WHERE c1 LIKE '%10-15!% off%' ESCAPE '!'

GO

D. 使用 [ ] 通配符

下例查找名字为 Cheryl 或 Sheryl 的作者。

USE pubs

GO

SELECT au_lname, au_fname, phone

FROM authors

WHERE au_fname LIKE '[CS]heryl'

ORDER BY au_lname ASC, au_fname ASC

GO

下例查找姓为 Carson、Carsen、Karson 或 Karsen 的作者所在的行。

USE pubs

GO

SELECT au_lname, au_fname, phone

FROM authors

WHERE au_lname LIKE '[CK]ars[eo]n'

ORDER BY au_lname ASC, au_fname ASC

GO


--
we drink green tea