zoukankan      html  css  js  c++  java
  • (数据科学学习手册28)SQL server 2012中的查询语句汇总

    一、简介

      数据库管理系统(DBMS)最重要的功能就是提供数据查询,即用户根据实际需求对数据进行筛选,并以特定形式进行显示。在Microsoft SQL Serve 2012 中,可以使用通用的SELECT语句进行查询操作,该语句具有非常灵活的使用方式和丰富的功能,即可以完成简单的单表查询,也可以完成复杂的连接查询和嵌套查询,本文就将对常用的大多数SQL中的数据查询语句进行总结和演示;

    二、实操部分

      本节中使用到的数据是美团的商家信息数据,隶属于数据库practice下的表T;

    2.1 使用SELECT语句进行查询

    2.1.1 对列查询

    /* 选择所有列 */
    USE practice
    GO
    SELECT * FROM T
    GO

    查询结果:

    /* 选择单个列 */
    USE practice
    GO
    SELECT 店铺名称 FROM T
    GO

    查询结果:

    /* 选择多个列 */
    USE practice
    GO
    SELECT 店铺名称,商品名称 FROM T
    GO

    查询结果:

    /* 为选择的列设置代号 */
    USE practice
    GO
    SELECT 店铺名称 AS Shop_Name,商品名称 AS Goods_Name FROM T
    GO

    查询结果:

    /* 利用字符查询表达式连接信息 */
    USE practice
    GO
    SELECT 店铺名称+菜系 AS 店铺属性 FROM T
    GO

    查询结果:

    /* 利用算数运算符生成新信息 */
    USE practice
    GO
    SELECT 价格/原价 AS 折扣 FROM T
    GO

    查询结果:

     2.1.2 去重查询

    /* 查询某列的去重信息 */
    USE practice
    GO
    SELECT DISTINCT 菜系 FROM T
    GO

    查询结果:

     2.1.3 限制查询的行数

    /* 查询前10行数据 */
    USE practice
    GO
    SELECT TOP 10 * FROM T
    GO

    查询结果:

     

    /* 查询前20%行的数据 */
    USE practice
    GO
    SELECT TOP 20 PERCENT * FROM T
    GO

    查询结果:

    2.2 使用WHERE子句进行条件查询

    2.2.1 使用比较运算符

    /* 查询菜系为火锅的所有数据 */
    USE practice
    GO
    SELECT * FROM T
    WHERE 菜系 = '火锅'
    GO

    查询结果:

    /* 查询价格大于等于100的所有数据 */
    USE practice
    GO
    SELECT * FROM T
    WHERE 价格 >= 100
    GO

    查询结果:

    /* 查询菜系非火锅的所有数据 */
    USE practice
    GO
    SELECT * FROM T
    WHERE 菜系 != '火锅'
    GO

    查询结果:

    2.2.2 使用逻辑运算符

    /* 查询菜系为火锅且价格大于100的所有数据 */
    USE practice
    GO
    SELECT * FROM T
    WHERE 菜系 = '火锅' AND 价格 >= 100
    GO

    查询结果:

    /* 查询菜系为火锅或甜品饮品的所有数据 */
    USE practice
    GO
    SELECT * FROM T
    WHERE 菜系 = '火锅' OR 菜系 = '甜点饮品'
    GO

    查询结果:

    /* 查询菜系不为火锅的所有数据 */
    USE practice
    GO
    SELECT * FROM T
    WHERE NOT 菜系 = '火锅'
    GO

    查询结果:

    2.2.3 使用LIKE运算符

      LIKE是模式匹配运算符,功能类似正则表达式,用于指定一个字符串是否与指定的字符串模式相匹配,使用LIKE运算符的代码格式如下:

    [NOT] LIKE '匹配字符串' [ESCAPE '<转义字符>']

    方括号中的内容是可选的,若一个LIKE关键词前带有NOT,则代表进行相反的操作(即指匹配未出现匹配字符串的目标);ESCAPE子句用于指定转义字符。匹配字符串可以是一个完整的字符串,也可以包含通配符% _ [] [^],这四种通配符的含义如下:

    LIKE子句中的通配符
    通配符 含义
    % 代表任意长度(长度可以为0)的字符串
    _ 代表任意单个字符
    [] 指定范围或集合内的任意单个字符
    [^] 不在指定范围或集合内的任意单个字符

     

    下面是通配符的一些示例:

     LIKE 'AB%'    返回以AB开头的任意长字符串

    LIKE '%ABC'       返回以ABC结尾的任意长字符串

    LIKE '%ABC%'         返回包含ABC的任意长字符串

    LIKE '_AB'                返回以AB结尾的长度为3的字符串

    LIKE '[ABC]%'          返回以A、B、C任意一个开头的任意长字符串

    LIKE 'L[^A]%'           返回以L开头,且第二个字符不是A的,任意长字符串

    我们在WHERE中使用LIKE子句来进行字符串的模式匹配:

    /* 查询所有连锁店(即名称里带有中文括号) */
    USE practice
    GO
    SELECT 店铺名称 FROM T
    WHERE 店铺名称 LIKE '%(%'
    GO

    查询结果:

    /* 查询所有川菜店 */
    USE practice
    GO
    SELECT 店铺名称+' '+菜系 AS 川菜店 FROM T
    WHERE 菜系 LIKE '川_'
    GO

    查询结果:

    /* 查询所有连锁店(即店铺名称以')'结尾) */
    USE practice
    GO
    SELECT 店铺名称 FROM T
    WHERE 店铺名称 LIKE '%[)]'
    GO

    查询结果:

     

     

    /* 查询所有非连锁店(即店铺名称不以')'结尾) */
    USE practice
    GO
    SELECT 店铺名称 FROM T
    WHERE 店铺名称 LIKE '%[^)]'
    GO

    查询结果:

     2.2.4 使用BETWEEN...AND...运算符

      运算符BETWEEN...AND...和NOT BETWEEN...AND...可以用来查找列的值在或不在指定的范围内。其中BETWEEN后是范围的下限(包括下限),AND后是范围的上限(包括上限)。

    /* 查询所有价格在100到200之间的商品名称及对应价格 */
    USE practice
    GO
    SELECT 商品名称,价格 FROM T
    WHERE 价格 BETWEEN 100 AND 200
    GO

    查询结果:

    /* 查询所有价格不在100到200之间的商品名称及对应价格 */
    USE practice
    GO
    SELECT 商品名称,价格 FROM T
    WHERE 价格 NOT BETWEEN 100 AND 200
    GO

    查询结果:

    2.2.5 使用IN运算符

      IN运算符可以用来表示列的值属于或不属于指定的集合。如果值属于制定的集合,返回true,否则返回false;

    /* 查询所有菜系在('火锅','烧烤烤肉','小吃快餐')中的店铺的名称及所属菜系 */
    USE practice
    GO
    SELECT 店铺名称,菜系 FROM T
    WHERE 菜系 IN('火锅','烧烤烤肉','小吃快餐')
    GO

    查询结果:

    /* 查询所有菜系不在('火锅','烧烤烤肉','小吃快餐')中的店铺的名称及所属菜系 */
    USE practice
    GO
    SELECT 店铺名称,菜系 FROM T
    WHERE 菜系 NOT IN('火锅','烧烤烤肉','小吃快餐')
    GO

    查询结果:

     2.2.6 使用IS NULL运算符

      运算符IS NULL可以判断列的值是否是NULL。如果是则返回true,否则返回false;

    USE practice
    GO
    -- 插入一行带有空值的样本
    INSERT INTO T VALUES(NULL,NULL,NULL,NULL,'川菜',100,230,'重庆')
    -- 查找商品名称为NULL的样本
    SELECT * FROM T
    WHERE 商品名称 IS NULL
    GO

    查询结果:

     2.3 排序查询

      使用ORDER BY子句可以按一个或多个属性列对数据进行排序。ORDER BY子句通常位于WHERE子句后面,默认的排序方式有两种(升序和降序),通过关键字ASC和DESC来指定。其中,ASC表示升序,DESC表示降序,默认为升序即ASC。当排序列包含空值NULL时,若使用ASC关键字,则排序列为空值的记录放在最后,若使用DESC关键字,则排序列为空值的记录放在最前,即默认NULL是最大的数值;

    /* 以价格列为排序列进行整体的降序排序 */
    USE practice
    GO
    SELECT * FROM T
    ORDER BY 价格 DESC
    GO

    查询结果:

    /* 以价格列为排序列进行商品属性的升序排序 */
    USE practice
    GO
    SELECT 店铺名称+' '+商品名称 AS 商品,价格 FROM T
    ORDER BY 价格
    GO

    查询结果:

    /* 以 价格列-店铺名称列 为主次排序列进行商品属性的升序排序 */
    USE practice
    GO
    SELECT 店铺名称+' '+商品名称 AS 商品,价格 FROM T
    ORDER BY 价格,店铺名称
    GO

    查询结果:

    2.4 使用聚合函数进行查询

      在SELECT语句中可以加上各种聚合函数进行统计并返回统计结果,可以得到很多有价值的信息;

      常见的聚合函数包括COUNT()、SUM()、AVG()、MAX()、MIN()。

    ——计数函数:COUNT([DISTINCT or ALL] 列名称 or *)

    ——求和函数:SUM([DISTINCT or ALL] 列名称)

    ——求平均值函数:AVG([DISTINCT or ALL] 列名称)

    ——求最大值函数:MAX([DISTINCT or ALL] 列名称)

    ——求最小值函数:MIN([DISTINCT or ALL] 列名称)

      其中,DISTINCT短语控制在计算时取消指定列中的重复值,即只处理唯一值;而ALL则控制计算时不取消指定列中的重复值,默认为ALL;下面以一系列的例子来演示各聚合函数:

    /* 计算表中菜系这一列不去重的情况下元素个数 */
    USE practice
    GO
    SELECT COUNT(菜系) AS 元素个数 FROM T
    GO

    查询结果:

    /* 计算表中菜系这一列不去重的情况下元素个数 */
    USE practice
    GO
    SELECT COUNT(DISTINCT 菜系) AS 菜系数量 FROM T
    GO

    查询结果:

    /* 计算表中价格这一列最大值与最小值 */
    USE practice
    GO
    SELECT MAX(价格) AS 最高价格,MIN(价格) AS 最小价格 FROM T
    GO

    查询结果:

    /* 计算表中价格这一列平均值与求和值 */
    USE practice
    GO
    SELECT AVG(价格) AS 平均价格,SUM(价格) AS 价格之和 FROM T
    GO

    查询结果:

    2.5 分组查询

      使用GROUP BY子句可以将查询结果按照某个字段或多个字段进行分组,字段值相等的为一组。这样做的目的是为了细化聚合函数的作用对象,即,如果未进行分组,则聚合函数将作用于所有对象;若进行分组,则聚合函数将作用于对应的每一个分组;下面是几个简单的例子:

    /* 以菜系作为分组依据列,查询各菜系的店铺数量及对应菜系 */
    USE practice
    GO
    SELECT COUNT(*) AS 各菜系店铺数量,菜系 FROM T
    GROUP BY 菜系
    GO

    查询结果:

     

     

    /* 以菜系作为分组依据列,查询各菜系的平均商品价格及对应菜系 */
    USE practice
    GO
    SELECT AVG(价格) AS 各菜系商品平均价格,菜系 FROM T
    GROUP BY 菜系
    GO

    查询结果:

      如果分组后需要按照一定的条件对这些组进行筛选,即最终只需要输出满足要求的组,则可以在GROUP BY之后指定HAVING语句添加筛选条件:

    /* 以菜系作为分组依据列,查询平均商品价格小于100的菜系及对应的平均商品价格 */
    USE practice
    GO
    SELECT AVG(价格) AS 各菜系商品平均价格,菜系 FROM T
    GROUP BY 菜系
    HAVING AVG(价格) < 100
    GO

    查询结果:

    *HAVING语句与WHERE语句的区别在于,他们的作用对象不同:WHERE语句作用于基表或视图,HAVING语句作用于分组,即其对象是分组后的组内对应值。

    2.6 嵌套查询

      在SQL语言中,将一个查询语句嵌套在另一个查询语句中的查询称作嵌套查询,又称子查询,SQL语言允许许多层嵌套查询,即一个子查询中还可以嵌套更多层子查询。在使用子查询时,注意事项如下:

      1.子查询必须用圆括号括起来;

      2.子查询中应避免使用ORDER BY语句;

      3.嵌套查询一般的求解方式时由里往外,即每一个子查询需要在更内层的查询结束后才会生效,子查询的结果是外层的父查询的查找条件。

    2.6.1 带IN的嵌套查询

      在嵌套查询中,子查询的结果往往是一个集合,所以IN是嵌套查询中最常见的谓词语句,其使用方式为:

    WHERE<条件表达式>

                                                                           IN (子查询)

    /* 利用嵌套查询选择商品名称中带有WiFi的店铺名称与商品名称,其中子查询查询商品名称满足要求的
    店铺名称与商品名称的集合,父查询查询店铺名称和商品名称与子查询输出集合相匹配的店铺名称及商品名称*/
    USE practice
    GO
    SELECT 店铺名称,商品名称 FROM T
    WHERE 店铺名称 IN
                    (SELECT 店铺名称 FROM T
                    WHERE 商品名称 LIKE '%WiFi%') AND
          商品名称 IN
                    (SELECT 商品名称 FROM T
                    WHERE 商品名称 LIKE '%WiFi%')
    GO

    查询结果:

    /* 利用嵌套查询查询商品名称中带有WiFi且价格低于100元的商品对应的店铺名称、商品名称、价格 */
    USE practice
    GO
    SELECT 店铺名称,商品名称,价格 FROM T
    WHERE 店铺名称 IN    -- 第一层子查询
                    (SELECT 店铺名称 FROM T
                    WHERE 商品名称 LIKE '%WiFi%' 
                    AND 价格 IN        -- 第二层子查询
                                  (SELECT 价格 FROM T
                                  WHERE 价格 <= 100))
    GO

    查询结果:

    2.6.2 带比较运算符的嵌套查询

      带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户能确切知道内层查询返回的是单值时,可以用=、>、<、>=、<=、!=、或<>等比较运算符,而且通过嵌套查询,我们可以实现在WHERE语句中使用聚合函数返回的单值,下面是两个个比较有代表性的例子:

    /* 使用嵌套循环查询所有商品中价格最贵的对应的菜系中所有商品的价格,用来进行比较 */
    USE practice
    GO
    SELECT 店铺名称,商品名称,价格,菜系 FROM T
    WHERE 菜系 = 
                (SELECT 菜系 FROM T
                WHERE 价格 = 
                            (SELECT MAX(价格) FROM T))    --使用嵌套查询便可在WHERE中使用聚合函数返回的值
    GO

    查询结果:

    /* 使用嵌套循环查询所有商品中价格小于等于平均价格的对应行的店铺名称,商品名称,价格,菜系 */
    USE practice
    GO
    SELECT 店铺名称,商品名称,价格,菜系 FROM T
    WHERE 价格 <= 
                (SELECT AVG(价格) FROM T)    --使用嵌套查询便可在WHERE中使用聚合函数返回的值
    GO

    查询结果:

    2.6.3 带ANY或ALL的嵌套查询

      我们前面介绍的嵌套查询的子查询局限性在于只能返回单值,我们可以通过结合ANY、ALL,实现子查询的多值返回查询。使用ANY或ALL谓词时,必须同时使用比较运算符,其对应含义如下表:

    ANY与ALL语义说明
    运算符 语义
    >ANY 大于子查询结果中的某个值
    >ALL 大于子查询结果中的所有值
    <ANY 小于子查询结果中的某个值
    <ALL 小于子查询结果中的所有值
    >=ANY 大于等于子查询结果中的某个值
    >=ALL 大于等于子查询结果中的所有值
    <=ANY 小于等于子查询结果中的某个值
    <=ALL 小于等于子查询结果中的所有值
    =ANY 等于子查询结果中的某个值
    =ALL 等于子查询结果中的所有值
    != or <>ANY 不等于子查询结果中的某个值
    != or <>ALL 不等于子查询结果中的所有值

    因为下面的内容经常涉及到多个表,因此介绍一下接下来会使用到的两个数据表:

    table1:美团商户商品信息表,包含的字段如下(我们利用SQL语句来查看字段名称):

    /* 查看table1的所有字段名 */
    USE sample
    GO
    SELECT  column_name 
    FROM    INFORMATION_SCHEMA.COLUMNS
    WHERE   table_name = 'table1'
    GO

    查询结果:

    table2:美团商户商家信息表,包含的字段如下:

    /* 查看table2的所有字段名 */
    USE sample
    GO
    SELECT  column_name 
    FROM    INFORMATION_SCHEMA.COLUMNS
    WHERE   table_name = 'table2'
    GO

    查询结果:

      下面对ANY及ALL的使用进行举例说明:

    /* 查询table1中本月销量比table2中本月销量最大值还高的商品的店铺名称与商品名称 */
    USE sample
    GO
    SELECT 店铺名称,本月销量 FROM table1
    WHERE 本月销量 > ALL(SELECT 本月销量 FROM table2)
    GO

    查询结果:

    USE sample
    GO
    SELECT * FROM table1
    WHERE 本月销售额 < ANY
                          (SELECT 本月销售额 FROM table2)
    GO

    查询结果:

    2.6.4 带EXISTS的嵌套查询

      EXISTS关键字后面的参数是一个任意的子查询。如果子查询有返回行(至少返回一行),那么EXISTS的结果为true,此时外层查询语句将执行查询;如果子查询没有返回任何行,那么EXISTS的结果为false,此时外层查询将不会执行;

    /* 以table1中是否有店铺名称为海底捞的数据作为判断依据 */
    USE sample
    GO
    SELECT * FROM table1
    WHERE EXISTS(SELECT * FROM table1 WHERE 店铺名称 = '海底捞')
    GO

    查询结果:

    可以看出,因为子查询没有查找到“海底捞”的记录,EXISTS返回false,导致外层的查询停止,没有返回任何行的数据

    /* 以table1中是否有店铺名称为小丸子料理的数据作为判断依据 */
    USE sample
    GO
    SELECT * FROM table1
    WHERE EXISTS(SELECT * FROM table1 WHERE 店铺名称 = '小丸子料理')
    GO

    查询结果:

    这里因为table1中存在小丸子店铺的记录:

    所以EXISTS返回true,使得外层查询得以实现

    2.7 集合查询

      SELECT查询语言的结果集往往是一个包含了多行数据(记录)的集合。而集合之间可以进行并、交、差等运算。在Microsoft SQL Server 2012 中,两个查询语句之间也可以进行集合运算,其中主要包括并运算UNION、交运算INTERSECT和差运算EXCEPT。

    2.7.1 并运算

      在进行并运算时,参与运算的两个查询语句,其结果中的列的数量和顺序必须相同,且数据类型必须兼容(即字符和数值必不兼容,而数值型与类型更细的比如双精度浮点数之间兼容)。

      默认情况下,UNION运算符将从结果中删掉重复的行,但可以通过使用UNION ALL运算符保留所有的行。

    /* 查询table1中一口酸牛奶和一只酸奶牛各自六月份的紫米露商品信息并取并集 */
    USE sample
    GO
    SELECT 商品名称,店铺名称 FROM table1
    WHERE 店铺名称 LIKE '一口酸牛奶%' AND 月份 = '2017-06-01 00:00:00.000' AND 商品名称 LIKE '%紫米露%'
    UNION ALL
    SELECT 商品名称,店铺名称 FROM table1
    WHERE 店铺名称 LIKE '一只酸奶牛%' AND 月份 = '2017-06-01 00:00:00.000' AND 商品名称 LIKE '%紫米露%'
    GO

    查询结果:

    /* 查询table1中一口酸牛奶和一只酸奶牛各自六月份的紫米露商品信息并取并集(去除重复项) */
    USE sample
    GO
    SELECT 商品名称 FROM table1
    WHERE 店铺名称 LIKE '一口酸牛奶%' AND 月份 = '2017-06-01 00:00:00.000' AND 商品名称 LIKE '%紫米露%'
    UNION
    SELECT 商品名称 FROM table1
    WHERE 店铺名称 LIKE '一只酸奶牛%' AND 月份 = '2017-06-01 00:00:00.000' AND 商品名称 LIKE '%紫米露%'
    GO

    查询结果:

    2.7.2 交运算

      交运算(INTERSECT)返回两个查询语句检索出来的共有行。

    /* 查询table1中本月销量在table1中第一且菜系为小吃快餐的店铺名称 */
    USE sample
    GO
    SELECT 店铺名称 FROM table1
    WHERE 本月销量 = (SELECT MAX(本月销量) FROM table1)
    INTERSECT
    SELECT 店铺名称 FROM table1
    WHERE 菜系 = '小吃快餐'

    查询结果:

    2.7.3 差操作

      差运算(EXCEPT)返回的是第一个查询语句查询结果有,但第二个查询语句的查询结果中没有的行。

    /* 查询table1中本月销量大于平均销量,但菜系不为火锅的记录对应的店铺名称、本月销量、菜系 */
    USE sample
    GO
    SELECT 店铺名称,本月销量,菜系 FROM table1
    WHERE 本月销量 > (SELECT AVG(本月销量) FROM table1)
    EXCEPT
    SELECT 店铺名称,本月销量,菜系 FROM table1
    WHERE 菜系 = '火锅'

    查询结果:

    2.8 连接查询

      在关系型数据库管理系统中,数据之间往往存在一定的联系,且分散存储在不同的数据表中。但是,在实际应用中往往需要同时从两个或两个以上的数据表中检索数据,并且每个表中的数据往往仍以单独的列出现在结果集中。实现从两个或两个以上表中检索数据且结果集中出现的列来自于两个或两个以上表中的检索操作称为连接技术。连接查询是关系型数据库中非常重要的查询方式,包括交叉连接、内连接、外连接三种。

      连接可以在SELECT语句的FROM子句或WHERE子句中建立,在FROM子句中指出连接时有助于将连接操作与WHERE子句中的搜索条件区别开,因此推荐前者,我在下面的演示中也将使用第一种风格的代码方式:

      在FROM子句中指定连接条件的语法格式为:

    SELECT <目标列表达式>

           FROM <表1> 连接类型 <表2>

    其中连接类型可以是交叉连接(CROSS JOIN)、内连接(INNER JOIN)、外连接(OUTER JOIN);ON子句指定连接条件,它由被连接表中的列和比较运算符、逻辑运算等构成。

    *连接可以对同一个表操作,也可以对多个表操作,对同一个表操作的连接称作自连接

     2.8.1 交叉连接查询

      交叉连接又称笛卡尔积,它返回两个表中所有数据行的全部组合,即结果集的数据行数等于两个表的数据行数之积,列为两个表的属性列之和。因此交叉连接的结果会产生很多没用的记录组合,且相当耗费时间,因此其实际意义不大,其语法格式如下:

    SELECT 字段列表 FROM 表1 CROSS JOIN 表2

    /* 将table1中的店铺名称与table2中的商家地址做交叉连接(注意要注明字段所属的表)  */
    USE sample
    GO
    SELECT TOP 10000 table1.店铺名称,table2.商家地址 FROM table1
    CROSS JOIN table2

    查询结果:

    可以看出,交叉连接无意义就在于它将第一个表中的m条记录分别与第二个表中的n条记录做组合,这就导致非常消耗计算机时间,这里我只选了前1000行做演示,因为这两个表m x n会到达上亿行;

    2.8.2 内连接查询

      内连接(INNER JOIN)使用比较运算符比较被连接列的列值,并列出与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、非等值连接和自连接。

    2.8.2.1 等值与非等值连接查询

      连接查询中用来连接两个表的条件称为连接条件或连接谓词,它的一般格式如下:

    表1.列1 比较运算符 表2.列2

      可以使用的比较运算符有:>、>=、<、<=、!=、<>,还可以用VETWEEN...AND...之类的谓词。当连接运算符为等号(=)时,称为等值连接。使用其他比较运算符就构成了非等值连接。

    /* 将table1中的商品名称、店铺名称与table2中的商家地址做内连接,连接条件为两个表中记录商家地址的列相等(等值连接)  */
    USE sample
    GO
    SELECT table1.商品名称 AS 商品名称,table1.店铺名称 AS 店铺名称,table2.商家地址
    FROM table1 INNER JOIN table2
    ON table1.店铺名称 = table2.商家名称
    GO

    查询结果:

    /* 将table1中的商品名称、本与销售额与table2中的商家名称、本月销售额做内连接,连接条件为table1中商品的销售额比table2中的商家的销售额还大  */
    USE sample
    GO
    SELECT TOP 100000 table1.商品名称, table1.本月销售额 AS 本月商品销售额,table2.商家名称,table2.本月销售额 AS 本月店家销售额
    FROM table1 INNER JOIN table2
    ON table1.本月销售额 > table2.本月销售额
    GO

    查询结果:

     2.8.2.2 自连接查询

      连接不仅可以在不同的之间进行,也可以在同一个表之间进行,这种连接称为自连接,又因为自连接中进行连接操作的实际上是一样的表,因此需要在查询语句中为表起代号:

    /* 使用自连接的方式查询table1中同属于自助餐的且销售额为高低关系的所有店铺的组合  */
    USE sample
    GO
    SELECT t1.商家名称,t1.本月销售额,t2.商家名称,t2.本月销售额,t2.菜系
    FROM table2 AS t1,table2 AS t2
    WHERE t1.菜系 = '自助餐' AND t1.本月销售额 > t2.本月销售额 AND t2.菜系 = '自助餐'
    GO

    查询结果:

    2.8.3 外连接查询

      在内连接操作中,只有满足连接条件的记录才能作为结果输出,但有时我们希望看到额外的不满足条件的数据,这时候可以使用外连接(OUTER JOIN)查询来实现:

      外连接有三种形式:

      1.左外连接(LEFT OUTER JOIN)

        左外连接的结果集中将包含左边表的所有记录(不管右边的表中是否存在满足条件的记录),以及右边表中满足连接条件的所有记录

      2.右外连接(RIGHT OUTER JOIN)

        与左外连接正好相反

      3.全连接(FULL OUTER JOIN)

        左外连接与右外连接的并集

    /* 使用左外连接的方式查询在table1和table2中菜系均为自助餐的记录  */
    USE sample
    GO
    SELECT TOP 10000 t1.店铺名称,t1.本月销售额,t2.商家名称,t2.本月销售额,t2.菜系
    FROM table1 AS t1 LEFT OUTER JOIN table2 AS t2
    ON t1.菜系 = '自助餐' AND t2.菜系 = '自助餐'
    GO

    查询结果:

    可以看出,因为采取的是左外连接,所以table1中的非自助餐店铺的名称也会显示出来,但因为不匹配连接条件,所以对应的table2中列的属性为NULL

    /* 使用右外连接的方式查询在table1和table2中菜系均为自助餐的记录  */
    USE sample
    GO
    SELECT TOP 10000 t1.店铺名称,t1.本月销售额,t2.商家名称,t2.本月销售额,t2.菜系
    FROM table1 AS t1 RIGHT OUTER JOIN table2 AS t2
    ON t1.菜系 = '自助餐' AND t2.菜系 = '自助餐'
    GO

    查询结果:

    可以看出,这时的效果与左外连接正好相反

      以上就是关于SQL server 2012中查询语句的基本用法,与其他的DBMS大同小异,今后会继续介绍其它类型的DBMS的相关知识,如有笔误,望指出。

        

  • 相关阅读:
    微信开发SDK使用教程--手机微信群聊新增通知服务端
    微信开发SDK使用教程--手机微信联系人信息上传服务端
    微信开发SDK使用教程--手机端接收发送朋友圈任务指令后数据回传服务端
    微信二次开发SDK使用教程--手机端向服务端发送回复朋友圈评论任务反馈服务端
    js 自执行匿名函数(转载)
    js继承中,原型属性的继承探究
    搭建邮件服务器和使用压测工具的总结
    window.onload和window.document.readystate的探究
    读艾伦的jQuery的无new构建,疑惑分析——jquery源码学习一
    WPF页面 全球化和本地化
  • 原文地址:https://www.cnblogs.com/feffery/p/8849853.html
Copyright © 2011-2022 走看看