2.1 比较运算符
比较运算符是SQL查询中最常见的、使用频率最高的运算符。利用比较运算符可以轻松地查询字段值为特定值或在某个特定区域的数据。本节通过5个实例介绍比较运算符中的等于、大于、小于、不等于等一系列比较运算符的使用方法以及实际运用中的注意事项。
疑难21 如何查询报考某专业的考生
如图2-1所示,该表是某学校招生考试的成绩表,其中包括报考各个专业的考生。如何利用SQL查询找出所有报考“英语”专业的考生?
■ 图2-1 考生成绩表
解决方案
通过SQL中的比较运算符中的等号运算符,来判断提取某一字段等于某个值的所有记录。
操作方法
步骤1 通过OLE DB方法找到外部数据源,保留“选择表格”对话框中对名称的默认选择,单击“确定”按钮,激活“导入数据”对话框,再单击“属性”按钮,在弹出的“连接属性”对话框中勾选“打开文件时刷新数据”复选框,然后单击“定义”选项卡,清空“命令文本”框中原有的内容。
步骤2 在“命令文本”框中输入以下SQL连接语句:
SELECT * FROM [考试成绩$A3:I90] WHERE 报考专业="英语"
单击“确定”按钮返回“导入数据”对话框,指定返回的查询数据位置为现有工作表的“$A$1”,然后单击“确定”按钮,即可得到报考“英语”专业的所有考生,结果如图2-2所示。
■ 图2-2 查询报考“英语”专业的所有考生
原理分析
※ 为SQL设置条件查询子句 ※
在SQL查询中,若要使用条件查询,必须设置WHERE子句。WHERE子句指定了一个条件,该条件对于想要出现在结果表中的所有数据都成立。可以采用如下形式的SQL语句来进行条件查询:
SELECT 字段 FROM 数据源 WHERE 条件表达式
参数字段代表需要在结果表中出现的各字段的名称,在Excel表格中即为列标题。如果要查询所有的字段,可以用*表示;若要查询表中的部分字段,可以列出各字段,字段之间用英文状态下的半角逗号(,)隔开。比如要查询“姓名”、“总成绩”字段,字段表达式可以写为
姓名,总成绩
数据源即为指定的表格数据区域。一般情况下,用户应该将数据放置于Excel表格中的最左上角,即数据区域从A1单元格开始。在这种情形下,只要用Excel工作表的名称加上$符号表示,并在两端加上方括号即可。比如[考试成绩$]。
※ 不以第一行为起点的数据表示 ※
有些情况下,表格中的数据并非从A1单元格开始,更多的时候以第二行为标题行或说明行。在此情况下,SQL语句中必须完整说明数据的真实区域。如本例表格中的前两行为说明性文字,而真正的数据区域从A3单元格开始,其数据区域为A3:I90,则该数据源应该以以下形式表示:
[考试成绩$A3:I90]
其中,A3表示数据区域的起点,即数据区域最左上角的单元格地址,I90表示数据区域的终点,即数据区域最右下角的单元格地址。两者用英文状态下的半角冒号(:)连接即表示该完整的数据区域。与表格名称组合在一起,即可表示指定表格中指定的数据区域,即数据源。
※ 等号运算符 ※
条件表达式即为查询的条件,在查询条件中使用各种运算符表示数据是否满足某些条件。在运算符中使用频率最高的就是等号(=)运算符。等号运算符用于设定指定字段等于指定值的查询条件,其使用格式如下:
expr = value
上述表达式用于判断指定字段(expr)的值是否等于某个特定的值value。若指定字段的值等于指定值,则表示该条件表达式成立,在结果表中的所有数据都将满足该条件。反之,结果表中则不会列出数据。
运用上述的条件查询,即可查询满足指定字段等于指定值的所有数据。在Excel中,虽然没有字段类型的设置,但是SQL会对数据进行一些基本的判断。对于数字列而言,可以简单地使用该表达式进行条件设置。如要查询“总成绩”为69的数据,可以采用以下条件表达式:
总成绩=69
当字段的值为文本时,则需要在条件中的指定值两边加上引号,如本例的条件表达式应该设置为:
报考专业= "英语"
需要注意的是,在Excel中,对于文本值,在表达式中的值两边需要加上引号,而不区分单引号和双引号。上述条件表达式与以下条件表达式等效,但是引号是必不可少的,而且必须是英文状态下的引号。
报考专业= ‘英语’
注意
在Excel SQL中的英文字母是区分大小写的,如“A”和“a”是不相等的。
疑难22 如何查询字段值中包含双引号的数据
许多时候,用户的数据是从网络上下载的,在这些下载的数据中包含了一些特殊符号的数据。如图2-3所示,该表是从网络上下载的一份有关世界知名湖泊的自然情况,可以发现:在湖泊名称的两端都加上了双引号。那么如何用SQL的条件查询语句查询“里海”的自然情况呢?
■ 图2-3 湖泊情况表
解决方案
在SQL条件表达式中,可以利用等号运算符查询字段满足为某个特定值的所有数据。这个特定值为文本时,需要在两边加上引号。当特定值本身就包含引号时,则必须采用特殊方法来表示引号。
操作方法
步骤1 通过OLE DB方法找到外部数据源,保留“选择表格”对话框中对名称的默认选择,单击“确定”按钮,激活“导入数据”对话框,再单击“属性”按钮,在弹出的“连接属性”对话框中勾选“打开文件时刷新数据”复选框,然后单击“定义”选项卡,清空“命令文本”框中原有的内容。
步骤2 在“命令文本”框中输入以下SQL连接语句:
SELECT * FROM [湖泊情况$] WHERE 湖泊 = ””"里海"””
单击“确定”按钮返回“导入数据”对话框,指定返回的数据查询位置为现有工作表的“$A$1”,然后单击“确定”按钮,即可得到“里海”的自然情况,结果如图2-4所示。
■ 图2-4 查询“里海”的自然情况
原理分析
※ 包含引号的数据表示 ※
在疑难21中介绍了如何查询指定字段值等于指定值的所有数据。当字段值为文本时,必须在文本两端加引号以表示其为文本。而当指定值中本身就包含引号时,则必须采用以下方法表示引号。
本例中,若待查询的数据“里海”没有双引号,则条件表达式可以表示为
湖泊=“里海”
而本例中,“里海”的两端本身就包含双引号,则不能单纯以“"里海"”的方式来表示字段值。在包含双引号的字符串中又要表示双引号,必须以两个连续的双引号表示,如下:
湖泊 = “””里海”””
在上述表示方式中,最外层的双引号表示该字段为文本值,在双引号中的连续两个双引号实质上表示一个双引号,这样就可以构造出两端包含双引号的“里海”。这样的表示方式在字符处理中经常用到。
在SQL执行条件查询的时候,会判断字段的类型。当字段类型为文本时,一定要在文本两端加上双引号或者单引号以表示其字段类型为文本。在此情形下,SQL语句会首先查找表示字段类型的标志型符号,即单引号或双引号,因而单引号和双引号有了特殊的意义。在查找表执行符号时,查找是从左向右的。在找到左侧的第一个双引号时,会查找紧接着的双引号以表示文本的结束。
如本例中的“里海”文本,SQL语句执行时最先找到最左侧的双引号,SQL查询就得知该字段值为文本类型,由于文本类型需要用两个双引号将文本内容包含起来,SQL查询会在找到最左边的双引号起依次向右查找另一个双引号。当采用“"里海"”的方式表示两端带有双引号的“里海”时,SQL查询会紧接着找到第二个双引号,查询机制会误认为这第二个双引号即表示文本的结束,从而不会继续右边字符的查找。但是在第二个双引号之后还有其他的字符,则查询机制会误认为语句有问题而拒绝执行。而在查找到最左边的双引号后,如果SQL查询找到两个连续的双引号,则查询机制会将这两个连续的双引号转义成一个双引号,会将该双引号表示在文本之内。因而在双引号中必须以两个连续的双引号表示一个双引号。
同样的查询机制在单引号表示文本时也存在:在找到第一个单引号时,会查找紧接着的单引号以表示文本的结束。
利用该特性,除了可以利用两个连续的双引号表示一个双引号外,也可以将最外层表示文本类型的标志性符号改为单引号。查询机制在找到第一个单引号后,会向右查找第二个单引号以表示文本的结束。在该情形下,双引号就表示双引号,而不再表示标志数据类型的符号,查询机制就会认为双引号是包含在文本中的。因而,本例的查询语句也可以写为如下形式:
SELECT * FROM [湖泊情况$] WHERE 湖泊 = ‘”里海”’
同样,在单引号作为文本标志符号时,要在其中表示单引号可以采用两个连续的单引号表示一个单引号。如果本例中“湖泊”字段值的两端是单引号,而不是双引号,则可以采用以下语句:
SELECT * FROM [湖泊情况$] WHERE 湖泊 = ‘’’里海’’’
或者
SELECT * FROM [湖泊情况$] WHERE 湖泊 = “’里海’”’
疑难23 如何查询指定日期的出口数据
如图2-5所示为该表某公司于2010年1月的出口数据,在众多的出口数据中经常需要找出某一天的数据进行分析。本例中如何用SQL查询2010年1月31日的出口数据?
■ 图2-5 出口数据表
解决方案
在SQL条件表达式中,可以利用等号运算符查询字段满足某个特定值的所有数据。这个特定值日期需要在两边加上符号“#”。
操作方法
步骤1 通过OLE DB方法找到外部数据源,保留“选择表格”对话框中对名称的默认选择,单击“确定”按钮,激活“导入数据”对话框,再单击“属性”按钮,在弹出的“连接属性”对话框中勾选“打开文件时刷新数据”复选框,然后单击“定义”选项卡,清空“命令文本”框中原有的内容。
步骤2 在“命令文本”框中输入以下SQL连接语句:
SELECT * FROM [出口数据$] WHERE 日期=#2010-1-31#
单击“确定”按钮返回“导入数据”对话框,指定返回的数据查询位置为现有工作表的“$A$1”,然后单击“确定”按钮,即可得到2010年1月31日的出口数据,结果如图2-6所示。
■ 图2-6 查询指定日期的出口数据
原理分析
※ 日期型数据表示 ※
在等号运算符的条件查询中,若要查询日期和时间类型的数据,需要在数据值两端加上井字符号(#)以表示数据类型为日期。
在Excel的SQL查询中,日期可以有多种表示方式。最符合中国人习惯的是“年-月-日”的表示方式,或者“年/月/日”的表示方式。年、月、日之间可以用“-”分隔,也可以用“/”分隔。在其他国家,也有“月/日/年”以及“日/月/年”的习惯表示方式。这两种表示方式都可以被SQL语句识别。本例中,若要查询2010年1月31日的出口数据,可以采用以下几种表示方式:
#2010/1/31# #1/31/2010# #31/1/2010# #1−31−2010# #31−1−2010#
本例中“月/日/年”和“日/月/年”的表示方式都能被识别而不发生混淆,其原因在于月份中最大的值为12,而本例中的31日是大于12的,因而SQL查询只会将31认为是日,而不会将其认为是月。所以在本例中上述几种表示方法均可实现。
当采用“月/日/年”或“日/月/年”的表示方式时,且遇到可能发生混淆的情形,如2010年1月2日,查询机制始终认为月份在日之前,即始终认为是“月/日/年”的表示方式。因而,如果分别采用“月/日/年”和“日/月/年”的表示方式来表示2010年1月2日,则表达式如下:
#1/2/2010# #2/1/2010#
由于1和2都小于12,SQL查询机制为避免混淆,总是认为月份在日期之前。因而,上述两个表达式尽管是用不同的日期表示方式来表示同一日期,SQL查询会认为上述两个表达式表示了不同的日期,分别是“2010年1月2日”和“2010年2月1日”。
综上所述,在表示日期时,除了在日期两端加上井字符号(#)外,月份应始终放在日之前,即采用“月/日/年”和“年/月/日”的表示方式,以避免在使用“日/月/年”的表示方式时,系统识别日期与用户期望日期不同而导致查询结果发生错误。
疑难24 如何查询啤酒销量超过50kL的信息
在进行条件查询的时候,通常需要查询一些指定数量之上或者指定数量以下的数据。如图2-7所示,该表为某公司各地区的啤酒销量。现在需要查询该公司啤酒销量大于50kL的数据,如何用SQL查询实现?
■ 图2-7 啤酒销量数据
解决方案
在SQL条件表达式中,可以利用大于号(>)运算符查询字段值大于某个特定值的所有数据。
操作方法
步骤1 通过OLE DB方法找到外部数据源,保留“选择表格”对话框中对名称的默认选择,单击“确定”按钮,激活“导入数据”对话框,再单击“属性”按钮,在弹出的“连接属性”对话框中勾选“打开文件时刷新数据”复选框,然后单击“定义”选项卡,清空“命令文本”框中原有的内容。
步骤2 在“命令文本”框中输入以下SQL连接语句:
SELECT * FROM [啤酒销量数据$A2:C7] WHERE [啤酒销量(kL)]>50
单击“确定”按钮返回“导入数据”对话框,指定返回的查询数据位置为现有工作表的“$A$1”,然后单击“确定”按钮,即可得到啤酒销量大于50kL的信息,结果如图2-8所示。
■ 图2-8 查询啤酒销量大于50kL的信息
原理分析
※ 带有括号的字段名表示方式 ※
本例中的啤酒销量字段之后有代表单位的字符,其单位两端带有半角的圆括号。由于SQL中函数运算同样带有半角圆括号,如果该字段简单地以“啤酒销量(kL)”表示,则SQL将认为该表达式中存在“啤酒销量”函数的运算而发生错误。为避免该错误,需要在该字段两端加上方括号,即“[啤酒销量(kL)]”以表示其整个字符串为字段名。
SQL查询中字段的方括号与圆括号是等价的,SQL都会将其认为是圆括号。如本例的“啤酒销量(kL)”字段为“啤酒销量[kL]”时,在表示该字段时同样采用“[啤酒销量(kL)]”。同理,若该字段为“[啤酒销量]”时,则其应该表示为“[(啤酒销量)]”(参见疑难8中的知识扩展)。
当括号为全角括号时,则不必在其两端再加上方括号。
※ 大于、小于等运算 ※
在SQL运算符号中,大于号(>)运算符可以用于查询大于某个数值的数据,其表达式类似于等于运算符。条件表达式格式如下:
expr > value
其中,expr为指定的字段或表达式,value为与字段或表达式比较的指定值。本例中,要查询啤酒销量大于50的信息,可以用以下表达式:
[啤酒销量(kL)]>50
在该表达式中,大于号(>)可以替换成其他比较符号实现不同的效果,具体如下:
[啤酒销量(kL)]>= 50啤酒销量大于或等于50 [啤酒销量(kL)]<50 啤酒销量小于50 [啤酒销量(kL)]<= 50啤酒销量小于或等于50
等号运算符就是比较大小的一种特殊情形,因而等号运算符的一些特殊规则同样适用于上述几种情形。如:日期两端必须加上井字符号(#),此时就分别表示在某日期之后(不包括当日)、在某日期之后(包括当日)、在某日期之前(不包括当日)、在某日期之前(包括当日)。
在实际运用中,条件表达式不局限于字段名在运算符左边而指定值在运算符右边的情形。将指定值和字段名位置对换也能被SQL识别。在使用等号运算的时候能够得到相同的结果,但在使用大于、大于或等于、小于、小于或等于运算符时,其含义却大不相同。如下列表达式表示啤酒销量小于50:
50<[啤酒销量(kL)]
因而,在使用上述运算符的时候需要特别注意,应该依据个人习惯统一条件表达式字段名和指定值的位置。
知识扩展
在SQL中,中文文本同样可以比较大小,但是其比较的结果依赖于操作系统和SQL数据库环境的排序机制。不同的操作系统和SQL数据库环境会导致不同的大小比较结果。由于机制非常复杂且不具有通用性,因而,一般不建议在SQL查询中对文本进行比较查询。
疑难25 如何查询某班外同学的考试成绩
如图2-9所示,该表为某学校某年级的考试成绩。现在需要将尖子班一班的同学剔除,并用其他班同学的考试成绩进行对比分析。如何用SQL查询实现?
■ 图2-9 考试成绩表
解决方案
在SQL条件表达式中,可以利用不等号(<>)运算符查询字段值不等于某个特定值的所有数据。
操作方法
步骤1 通过OLE DB方法找到外部数据源,保留“选择表格”对话框中对名称的默认选择,单击“确定”按钮,激活“导入数据”对话框,再单击“属性”按钮,在弹出的“连接属性”对话框中勾选“打开文件时刷新数据”复选框,然后单击“定义”选项卡,清空“命令文本”框中原有的内容。
步骤2 在“命令文本”框中输入以下SQL连接语句:
SELECT * FROM [考试成绩$] WHERE [班级_(一年级)]<>"一班"
单击“确定”按钮返回“导入数据”对话框,指定返回的查询数据位置为现有工作表的“$A$1”,然后单击“确定”按钮,即可得到某班以外同学的考试成绩,结果如图2-10所示。
■ 图2-10 查询一班以外的同学考试成绩
原理分析
本例中,“班级”字段单元格中有一个换行符(用组合键【Alt+F10】生成),该换行符由于不能在SQL中直接表示,而采用下画线(_)表示。因而,在查询该字段时,以“[班级_(一年级)]”表示(具体请参见疑难47)。
※ 不等号比较运算 ※
在SQL运算符号中,不等号(<>)运算符可以用于查询不等于某个数值的数据。不等号运算查询结果为等号运算查询结果的反集,两者查询结果合并即为完整的原始数据。
expr <> value
在使用不等号运算时,可以进行数字、文本、日期的条件查询。