第六章:SQL Server2019数据库之 SELECT 语句的深入使用

目录

  • 一、范围查询
    • 1、查询两个值、两个日期之间的数据
    • 2、在 BETWEEN 中使用日期函数
    • 3、日期时间查询
  • 二、使用逻辑运算符过滤数据
    • 1、使用 AND 运算符
    • 2、使用 OR 运算符
    • 3、使用 NOT 运算符
  • 三、使用 IN 操作符过滤数据
    • 1、使用 IN 查询数据
    • 2、使用 NOT IN 查询数据
  • 四、模糊查询

学前必备知识

  1. 第一章:SQL Server 数据库环境搭建与使用
  2. 第二章:SQL Server2019 数据库的基本使用之图形化界面操作
  3. 第三章:SQL Server2019数据库 之 开启 SQL 语言之旅
  4. 第四章:SQL Server2019数据库 之 综合案例练习、 使用SQL语句插入数据、更新和删除数据
  5. 第五章:SQL Server2019数据库之 综合案例练习、开启 SELECT 语句之旅

一、范围查询

范围查询是用来查询给定的两个值之间的数据,通常使用 BETWEEN.…AND 和 NOT.…BETWEEN…AND 来指定范围条件。使用 BETWEEN…AND 查询条件时,指定的第一个值必须小于第二个值。因为 BETWEEN.…AND 实质是查询条件 大于或等于第一个值,并且小于或等于第二个值 的简写形式,即 BETWEEN…AND 要包括两端的值,等价于比较运算符 >=....<=

1、查询两个值、两个日期之间的数据

【例1】在 student 表中,显示年龄在 20~22 岁之间的学生信息。SQL 语句如下:

SELECT * FROM student WHERE 年龄 BETWEEN 20 AND 22;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第1张图片
【例2】在 student 表中,显示年龄不在 20~22 岁之间的学生信息。SQL 语句如下:

SELECT * FROM student WHERE 年龄 NOT BETWEEN 20 AND 22;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第2张图片
【例3】在 bookinfo_zerobasis 零基础系列图书信息表中,查询数据录入时间在 2017年12月1日 和 2018年12月1日 之间的图书信息。SQL 语句如下:

SELECT ISBN,BookName,INTime AS '录入时间' 
FROM bookinfo_zerobasis
WHERE INTime BETWEEN '2017-12-1' AND '2018-12-1';

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第3张图片

2、在 BETWEEN 中使用日期函数

通过 GETDATE() 函数和 DATEADD() 函数,获取当天的日期和前一天的日期,再通过使用 BETWEEN---AND 来查询出在这两个日期之间的数据。例如,使用如下代码可获得当天的日期:

SELECT GETDATE();

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第4张图片
【例4】在 bookinfo_zerobasis 零基础系列图书信息表中,查询数据录入时间在 2017年10月26日 前一天的图书信息。SQL 语句如下:

SELECT ISBN,BookName,INTime AS '数据录入时间' 
FROM bookinfo_zerobasis
WHERE INTime BETWEEN DATEADD(DAY,-1,'2017-10-26') AND '2017-10-26';

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第5张图片

3、日期时间查询

在不同的 DBMS 中,系统都提供了许多用于处理日期和时间的函数,通过这些函数可以实现计算特定日期和时间。

1、转换日期格式

有时数据库表中存储的日期可能会是不规范的日期形式,如 21.04.07。为了方便用户的查看,需要将日期转换为四位数的年份,同时改变日期格式如 2021-04-07(“年-月-日”格式)。为了解决这一问题,从以下两点来进行介绍。

(1) 把长日期格式数据转换为短日期格式数据

函数表达式 SELECT CONVERT(CHAR(10),GETDATE(),120); 可以将日期转换成 yyyy-mm-dd 格式时间。其中,120 是格式代码,CHAR(10) 是指取出前 10 位字符。SQL Server 数据库并不支持分开的 TIME、DATE 和 TIMESTAMP 数据类型,而是支持单一的 DATETIME 数据类型,用于定义保存符合的日期和时间值。在 SOL Server 中,可使用 CONVERT 函数实现类型的转换。语法格式如下:

CONVERT(date_type[(length)],expression,style)

参数说明:

  1. date_type:要转换的数据类型。
  2. expression:DATETIME 类型的数据。
  3. style:指定转换形式。其取值不同则对应的日期、时间格式将不同。style 参数不同取值所对应的日期、时间格式如下表所示:
    第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第6张图片
    第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第7张图片
    在这里插入图片描述

(2) 将日期格式中的 - 转换为 /。REPLACE() 函数可以实现寻找列值中的 -,将其替换成 / 的功能。

【例5】将如 2021-04-07 11:49:23.030 的日期格式转换成如 2021/04/07 的日期格式。SQL 语句如下:

SELECT REPLACE(CONVERT(CHAR(10), GETDATE(), 120), '-', '/');

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第8张图片
2、计算两个日期的间隔天数

要想计算两个日期的间隔天数,可以使用 DATEDIFF() 函数实现。DATEDIFF() 函数的语法格式如下:

DATEDIFF(datepart, startdate, enddate)

参数说明:

  1. datepart:规定了应在哪一日期部分计算间隔差额的参数。SQL Server 识别的日期部分与缩写如下表所示:
    第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第9张图片
  2. startdate:计算的开始日期。其返回值为 datetime 或 smalldatetime 值或日期格式字符串的表达式。
  3. enddate:计算的终止日期。返回值为 datetime 或 smalldatetime 值或日期格式字符串的表达式。

【例6】例如,利用 DATEDIFF() 函数查询 2021年4月7日 到 2021年3月29日 之间的天数。SQL 语句如下:

SELECT DATEDIFF(DAY, '2021-3-29', '2021-4-7') AS '科目二考试通过天数';

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第10张图片
注意: enddate 减 startdate,如果 startdate 比 enddate 晚,则返回负值;当结果超出整数值范围,DATEDIFF 将产生错误。
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第11张图片
3、按指定日期查询数据

(1) DAY() 函数。DAY() 函数返回代表指定日期的天的日期部分的整数。其语法格式:

DAY(date)

参数说明:

  1. date:类型为 datetime 或 smalldatetime 的表达式。
  2. DAY() 函数返回值的数据类型为 int。

下面举例介绍一下 DAY() 函数的用法,返回月份值,SQL 语句如下:

SELECT DAY(0) AS MY_DAY1, DAY('04/07/2021') AS MY_DAY2;
-- 注意:SQL Server将date为0解释为01/01/1900。

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第12张图片
(2) MONTH() 函数。要实现按月查询数据可以使用日期函数 MONTH()。该函数的语法格式如下:

MONTH(date)

参数说明:

  1. date 返回 datetime 或 smalldatetime 类型的值或日期格式字符串的表达式。
  2. MONTH() 函数返回值的数据类型为 int。

MONTH() 函数能够将日期时间表达式 date 中的月份返回,返回的月份以数值1~12 来表示,1 代表一月、2 代表二月,以此类推。同样需要注意的是如果将 date 设置为 0,SQL Server 会将 0 视为 1900年1月1日。下面举例介绍一下 MONTH() 函数的用法。如下面的示例从日期 04.07.2021 中返回月份数,返回结果为 4。

SELECT MONTH('04.07.2021');  -- 4

(3) YEAR() 函数。YEAR() 函数用于返回表示指定日期中的年份的整数。其语法格式如下:

YEAR(date)

参数说明:

  1. date: datetime 或 smalldatetime 类型的表达式。
  2. YEAR() 函数返回值的数据类型为 int。

注意:

  1. 此函数等价于 DatePart(yy, date)。
  2. SQL Server 将 0 解释为 01/01/1900。

下面举例介绍一下 YEAR() 函数的用法,如下面示例返回指定日期的年份信息:

SELECT 
YEAR(-1) AS MY_YEAR1,
YEAR(-2) AS MY_YEAR2,
YEAR(0) AS MY_YEAR3,
YEAR(9) AS MY_YEAR4,
YEAR('04/07/2021') AS MY_YEAR5,
DATEPART(yy, '04/07/2021') AS MY_YEAR6;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第13张图片
【例7】按指定日期的月和年查询 bookinfo 图书信息表中图书的出版日期在 2016年 的图书信息。SQL 语句如下:

SELECT BookName,Type,pDate FROM bookinfo
WHERE YEAR(pDate)=2015;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第14张图片
小结:通过本节的学习,不仅需要掌握使用 BETWEEN…AND 语句进行范围查询,可以查询数字、日期之间的范围,还可以通过使用 NOT…BETWEEN…AND 语句来实现不在两个数之间的数据查询。除了范围查询之外,还介绍了日期时间的查询语句及用到的时间日期函数。

二、使用逻辑运算符过滤数据

如果想把几个单一条件组合成一个复合条件,这就需要使用逻辑运算符 NOT、AND 和 OR 才能完成复合条件查询。本小节将介绍在 SELECT 语句中使用逻辑运算符进行查询的方法。

1、使用 AND 运算符

在查询表时,如果想要满足两个给定的条件,可以在 WHERE 子句中使用 AND 运算符来实现。AND 运算符表示 与(并且) 的关系,在进行查询时,既要满足给定的第一个条件,也要同时满足给定的第二个条件,如果不满足两个查询条件的其中一个,这样的记录就会被排除掉。AND 运算符的真值表如下:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第15张图片
【例8】在 goods 商品信息表中,查询商品的本店价格(shop_price) 大于 3000 元并且小于 6000 元的所有商品的 id(goods_id)、名称(goods_name)和本店价格(shop_price)。SQL 语句如下:

SELECT goods_id,goods_name,shop_price 
FROM goods 
WHERE shop_price > 3000 AND shop_price < 6000;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第16张图片
说明:在定义查询语句时,在WHERE子句中可以设置多个筛选条件,可以同时使用多个AND运算符来连接多个条件表达式,只有同时满足所有查询条件的记录才会被查询出来。

【例9】按指定日期的月和年查询 bookinfo 图书信息表中 零基础系列 图书的出版日期在 2017年10月份 的图书信息。SQL 语句如下:

SELECT BookName,Type,pDate FROM bookinfo
WHERE YEAR(pDate)=2017 AND MONTH(pDate)=10 AND Type='零基础系列';

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第17张图片

2、使用 OR 运算符

在查询表时,如果想要满足两个给定条件的其中一个时,可以在 WHERE 子句中使用 OR 运算符来实现。OR 运算符表示 的关系,即满足第一个给定的条件或满足第二个给定的条件,如果不满足两个查询条件中的任何一个,这样的记录就会被排除掉。OR 运算符的真值表如下表所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第18张图片
【例10】用 OR 进行查询。查询学号是 B001 或者是 B003 的学生信息。SQL 语句如下:

USE student;
SELECT * FROM student WHERE 学号='B001' OR 学号='B003';

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第19张图片
同样,在WHERE语句中可以同时使用多个OR运算符来连接多个条件表达式,只要满足任何一个查询条件的记录就会被查询出来。

【例11】用 OR 进行查询。查询学号是 B001 或者是 B003 或者是年龄为 20 岁的学生信息。SQL 语句如下:

SELECT * FROM student WHERE 学号='B001' OR 学号='B003' OR 年龄=20;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第20张图片

3、使用 NOT 运算符

在查询表时,如果需要查询不满足给定条件的数据,可以在 WHERE 子句中使用 NOT 运算符来实现。NOT 运算符表示 的关系,即不满足所给定的条件。

【例12】查询年龄不为 20 岁的学生信息。SQL 语句如下:

SELECT * FROM student WHERE NOT 年龄=20;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第21张图片
在查询中也可以将 AND 运算符、OR 运算符和 NOT 运算符综合起来使用,但这 3 个运算符拥有不同的优先顺序,它们的优先级别按照由高到低的排列顺序如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第22张图片
即 NOT 优先级最高,AND 次之,OR 的优先级最低。对运算符优先级别的了解,在使用时非常重要。如果不掌握运算符的优先级别,在使用时就达不到预期的效果。

【例13】在 goods 商品信息表中,应用 OR 运算符和 AND 运算符组合查询商品信息,查询出商品分类id(cat_id)为 191,或商品分类 id 为 123,并且商品的本店价格(shop_price)大于 2000 元的所有商品。SQL 语句如下:

USE shop;
SELECT cat_id,goods_name,shop_price 
FROM goods
WHERE cat_id=191 OR cat_id=123 AND shop_price>2000;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第23张图片
由上图中的运行结果可以看出,商品分类 id 为 191 并且商品本店价格小于 2000元 的商品也被查询出来,显然没有达到预期的效果。出现该问题的原因在于求值的顺序,SQL 在处理 OR 运算之前,会优先处理 AND 运算,所以在结果中查询出商品分类 id 为 123 且商品本店价格大于 2000元 的商品,以及商品分类 id 为 191 的所有商品。要解决这个问题,可以使用小括号对运算符和查询条件进行分组。SQL 语句如下:

USE shop;
SELECT cat_id,goods_name,shop_price 
FROM goods
WHERE (cat_id=191 OR cat_id=123) AND shop_price>2000;

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第24张图片
说明:因为小括号具有比 AND、OR 或 NOT 运算符更高的优先级,所以在 WHERE 子句中使用不同的逻辑运算符时,都应该使用小括号对运算符和查询条件进行明确分组。

【练习1】在 goods 商品信息表中,使用 NOT 运算符和 AND 运算符查询商品信息,查询出商品分类id(cat_id)不是 191 和 123 的所有商品分类 id、商品名称(goods_name)和商品本店价格(shop_price)。

【练习2】在 student 表中,要查询年龄大于21岁女生或者年龄大于等于19岁的男生信息。

【练习3】在 student 表中,查询年龄大于20岁的女生或者年龄大于22岁的男生,并且电话号码都是 23451 的学生信息。

总结:本小节主要讲解了将多个条件表达式通过使用逻辑运算符结合在 WHERE 子句中来完成查询功能。通过本小节的学习,读者可以掌握 AND、OR 和 NOT 运算符的使用,并了解这些运算符的优先级。

三、使用 IN 操作符过滤数据

在对表中的数据进行查询时,有时需要查询出多个条件中满足一个条件的数据,这种情况可以使用 OR 运算符,但是对于较多的条件来说使用 OR 运算符并不方便,例如,在表中查询出省份为 吉林省、辽宁省、黑龙江省 的数据,使用 OR 运算符就会比较烦琐。此时可以使用 IN 操作符代替 OR 运算符来完成查询任务。

1、使用 IN 查询数据

使用 IN 操作符可以判断某个字段的值是否在指定的集合中。如果字段的值在集合中,则满足查询条件,该记录将被查询出来;如果不在集合中,则不满足查询条件。使用 IN 操作符查询数据的基本语法格式如下:

SELECT column_name
FROM table_name
WHERE column_name IN (value1, value2,. . .)

参数说明:

  1. column_name:表示需要查询列的列名。
  2. table_name:表示需要查询的表名。
  3. column_name:表示需要指定查询条件的列。
  4. value:表示值列表。

【例14】在 goods 商品信息表中,查询出商品分类 id(cat_id)为 191、123 和 131 的商品分类 id、商品名称(goods_name)和商品本店价格(shop_price)。SQL 语句如下:

SELECT cat_id,goods_name,shop_price 
FROM goods
WHERE cat_id IN(191,123,131);

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第25张图片
【练习4】在 course 表中,查询 课程编号 是 k01,k03,k04 的课程信息。

在 IN 操作符后的值列表中还可以使用算术表达式。【例15】在 goods 商品信息表中,查询出商品本店价格(shop_price) 为 3799-100、3799 和 3799+100 三种价格的商品名称(goods_name)和商品本店价格。SQL 语句如下:

USE shop;
SELECT goods_name,shop_price FROM goods 
WHERE shop_price IN(3799-100,3799,3799+100);

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第26张图片
在使用 IN 操作符对数据进行查询时,不但可以使用数值类型和字符类型的数据作为值列表,还可以使用列名作为值列表。下面使用数值作为 IN 操作符的查询条件将两个列名作为值列表来实现查询。

【例16】在 goods 商品信息表中,查询出商品的市场价格(market price)或本店价格(shop_price)为 3799 的商品名称(goods_name)、商品市场价格和本店价格。SQL 语句如下:

SELECT goods_name,market_price,shop_price FROM goods
WHERE 3799 IN(market_price, shop_price);

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第27张图片

2、使用 NOT IN 查询数据

NOT IN 操作符可以查询出给定条件以外的数据。利用 NOT IN 操作符查询条件的基本语法格式如下:

SELECT column_name
FROM table_name
WHERE column_name NOT IN (value1, value2,. . .)

参数说明:

  1. column_name:表示需要查询列的列名。
  2. table_name:表示需要查询的表名。
  3. column_name:表示需要指定查询条件的列。
  4. value:表示值列表。

【例17】在 course 表中,课程代号不是 k01、k03 和 k04 的课程信息。SQL 语句如下:

USE student;
SELECT * FROM course
WHERE 课程代号 NOT IN('k01','k03','k04');

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第28张图片
使用NOT IN 查询后两行的数据,前提条件是需要知道表中共有多少行数据。例如,数据表中有 5 行数据,在查询中先通过使用 TOP 关键字将前 3 行数据查询出来,再使用 NOT IN 操作符将后两行数据查询出来。

【例18】在 course 表中,有5条记录,查询最后两行的数据。SQL 语句如下:

SELECT * FROM course
WHERE 课程代号 NOT IN(SELECT TOP 3 课程代号 FROM course);

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第29张图片
总结:本小节主要讲解了在 WHERE 子句中通过 IN 操作符和 NOT IN 操作符来实现查询功能。通过本小节的学习,读者可以掌握 IN 操作符和 NOT IN 操作符的使用。

四、模糊查询

在对表中数据进行查询时,常常会用到模糊查询。模糊查询可以轻松地查询出比较模糊的数据。例如,查询姓名列中姓 诸葛 的数据、查询用户邮箱列中含有 qq 的数据等。

前面介绍的所有操作符都是针对已知的值进行过滤的。无论是匹配一个值还是多个值,或者查询某个范围的值,在过滤数据时提供的这些值都是已知的。而有时在查询表中数据时需要返回符合某种匹配格式的所有记录,这时就需要使用 LIKE 或 NOT LIKE 谓词来指定模糊查询条件。定义模糊查询条件需要使用通配符在字符串内查找指定的搜索模式,所以读者需要了解通配符及其含义。通配符即用来匹配值的一部分的特殊字符。常用的通配符及其含义如下表所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第30张图片
LIKE 谓词通过使用通配符可以指定任何的模糊查询条件,下面将介绍几个使用 LIKE 谓词来实现模糊查询的例子:

-- 1.查询出某列中包含 amo 字符的数据,其中amo可以出现在任意位置。
WHERE 列名 LIKE '%amo%'
-- 2.查询出某列中包含amo字符的数据,其中amo出现在开头位置。
WHERE 列名 LIKE 'amo%'
-- 3.查询出某列中包含amo字符的数据,其中amo出现在结尾位置。
WHERE 列名 LIKE'%amo'
-- 4.查询出某列中前两个字符为am、后一个字符为任意字符的数据。
WHERE 列名 LIKE 'am_'
-- 5.查询出某列中前一个字符为任意字符、后两个字符为mo的数据。
WHERE 列名 LIKE '_mo'
-- 6.查询出某列中以a字符或b字符开头的数据
WHERE 列名 LIKE '[ab]%'
-- 7.查询出某列中以a~e之间的字符开头的数据,其中包括a和e
WHERE 列名 LIKE '[a-e]%'
-- 8.查询出某列中不是以a字符或b字符开头的数据
WHERE 列名 LIKE '[^ab]%'
-- 9.查询出某列中不是以 a~e 之间的字符开头的数据
WHERE 列名 LIKE '[^a-e]%'

【练习5】在 student 表中,查询姓 并且联系方式是以 2 打头的学生信息。
【练习6】在 student 表中,查询姓 并且名字只有两个字的学生信息。
【练习7】在 student 表中,查询姓 并且末尾字是 的学生信息。
【练习8】在 student 表中,查询联系方式以 3451 结尾并且开头数字位于 1~5 之间的学生信息。
【练习9】在 grade 表中,查询学号是 B001B003 之间的学生成绩信息。
【练习10】在 student 表中,查询联系方式以 3451 结尾,但不以 2 开头的学生信息。

NOT LIKE 的含义与 LIKE 关键字正好相反,查询结果将返回不符合匹配模式查询。

在使用通配符查询数据时,数据中可能也包含着通配符。例如,表中的某个列可能存储着包含百分号 % 的折扣值,此时如果使用 % 通配符进行数据查询,可能会查不到想要查询的数据,这时可以使用 ESCAPE 关键字定义转义字符来解决这个问题。当把定义的转义字符放在通配符之前时,该通配符就被解释为普通字符。例如,查询出某列中以字符串 10% 结尾的数据,代码如下:

WHERE 列名 LIKE '%10#%' ESCAPE '#';

上述代码中,第一个 % 为通配符,# 为定义的转义字符,其后面的 % 即被解释为普通字符。

【例19】在 users 用户信息表中,查询用户注册邮箱(email) 名称中含有字符 _ 的用户 id(user_id)、注册邮箱和用户出生日期(birthday)。SQL 语句如下:

USE shop;
SELECT user_id,email,CONVERT(VARCHAR(10),birthday,120) AS birthday
FROM users
WHERE email LIKE '%/_%' ESCAPE '/';

查询结果如下图所示:
第六章:SQL Server2019数据库之 SELECT 语句的深入使用_第31张图片
总结:本小节主要讲解了什么是通配符,以及如何在 WHERE 子句中使用通配符。通过本小节的学习,读者可以掌握应用 LIKE 谓词和通配符进行模糊查询。

你可能感兴趣的:(SQLServer2019,环境搭建及使用,sql,sqlserver2019,数据库)