9 单表查询
单表查询的select语句的语法格式如下:
select columnl, column2... from 数据源 [where condition]
where条件用于确定选择哪些行,只有满足where条件的记录才会被选择出来;如果没有where条件,则默认选出所有行。如果想选择出所有列,则可使用星号(*)代表所有列。
下面的SQL语句将会选择出 teacher_table表中的所有行、所有列的数据。
select * from teacher_table;
如果增加where条件,则只选择出符合where条件的记录。如下SQL语句将选择出student _table表中java teacher值大于3的记录的student_name列的值
select student_name from student_table where java_teacher > 3;
concat函数
MySQL中没有提供字符串连接运算符,即无法使用加号(+)将字符串常量、字符串变量或字符串列连接起来。MySQL使用concat函数来进行字符串连接运算。
SQL语句如下:
#选择出teacher _name和'xx'字符串连接后的结果 select concat(teacher_name, 'xx') from teacher table;
对于MySQL而言,如果在算术表达式中使用null,将会导致整个算术表达式的返回值为null;如 果在字符串连接运算中出现null,将会导致连接后的结果也是null。如下SQL语句将会返回null
select concat(teacher name, null) from teacher table;
对某些数据库而言,如果让字符串和null进行连接运算,它会把null当成空字符串处理。
如果不希望直接使用列名作为列标题,则可以为数据列或表达式起一个别名,为数据列或表达式起别名时,别名紧跟数据列,中间以空格隔开,或者使用as关键字隔开。SQL语句如下:
select teacher_id + 5 as MY_ID from teacher table;
为列起别名,可以改变列的标题头,用于表示计算结果的具体含义。如果列别名中使用特殊字符(例如空格),或者需要强制大小写敏感,都可以通过为别名添加双引号来实现。SQL语句如下:
#可以为选出的列起别名,别名中包括单引号字符,所以把别名用双引号引起来 select teacher id + 5 as "MY'id" from teacher table;
如果需要选择多列,并为多列起别名,则列与列之间以逗号隔开,但列和列别名之间以空格隔开。SQL语句如下:
select teacher_id + 5 My_ID, teacher_name 老师名 from teacher_table;
不仅可以为列或表达式起别名,也可以为表起别名,为表起别名的语法和为列或表达式起别名的语 法完全一样,SQL语句如下:
select teacher_id + 5 MY_ID, teacher_name老师名 # 为teacher_table起别名 t from teacher_table t;
前面已经提到,列名可以当成变量处理,所以运算符也可以在名列之间进行运算,SOL语句如下
select teadher_id + s MY_ID, concat ( teacher_name, teacher_id ) teacher_name from teacher_table where teacher_id * 2 > 3;
甚至可以在 select、where子句中都不出现列名,SQL语句加下
select 5+4 from teacher table where 2<9;
这种情况比较特殊:where语句后的条件表达式总是true,所有会把teacher table表中的每条记录都选择出来——但SOL语句没有选择任何列,仅仅选择了一个常量,所以SOL会把该常量当成一列,teacher_table表中有多少条记录,该常量就出现多少次。
对于选择常量的情形,指定数据表可能没有太大的意义,所以MySQL提供了一种扩展语法,允许select语句后没有from子句,即可写成如下形式:
select 5 + 4;
上面这种语句并不是标准SQL语句。例如,Oracle就提供了一个名为dual的虚表(最新的MySQL数据库也支持dual虚表),它没有任何意义,仅仅相当于from后的占位符。如果选择常量,则可使用如下语句:
select 5+4 from dual;
select默认会把所有符合条件的记录全部选出来,即使两行记录完全一样。如果想去除重复行,则可以使用distinct关键字从查询结果中清除重复行。比较下面两条SQL语句的执行结果:
#选出所有记录,包括重复行 select student_name,java_teacher from student_table; #去除重复行 select distinct student_name,java_teacher from student_table;
注意:
使用distinct去除重复行时,distinct紧跟select关键字。它的作用是去除后面字段组 合的重复值,而不管对应记录在数据库里是否重复。例如,(1,‘a’,‘b’)和(2,‘a’,‘b’)两条记录在数据库里是不重复的,但如果仅选择后面两列,则distinct会认为两条记录重复。
前面已经看到了where子句的作用——可以控制只选择指定的行。因为where子句里包含的是一个条件表达式,所以可以使用>、>=、<、<=、=和<>等基本的比较运算符。SQL中的比较运算符不仅可以比较数值之间的大小,也可以比较字符串、日期之间的大小。
注意:
SQL中判断两个值是否相等的比较运算符是单等号,判断不相等的运算符是<>;SQL 中的赋值运算符不是等号,而是冒号等号(:=)
除此之外,SQL还支持如表13.3所示的特殊的比较运算符
between
下面的SQL语句选出student id大于等于2,且小于等于4的所有记录。
select * from student table where student_id between 2 and 4;
使用between vall and val2必须保证vall小于val2,否则将选不出任何记录。除此之外,between val andvaD中的两个值不仅可以是常量,也可以是变量,或者是列名也行。如下SOL语句选出java_teache 小于等于2,student_id大于等于2的所有记录。
select * from student_table where 2 between java_teacher and student_id;
in
使用in比较运算符时,必须在in后的括号里列出一个或多个值,它要求指定列必须与in括号里任意一个值相等。SQL语句如下:
#选出student_id为2或4的所有记录 select * from student_table where student_ id in(2,4);
与之类似的是,in括号里的值既可以是常量,也可以是变量或者列名,SQL语句如下:
#选出student_id、 java_teacher列的值为2的所有记录 select * from student table where 2 in(student_id, java_teacher);
like 模糊查询
like运算符主要用于进行模糊查询,例如,若要查询名字以“张”开头的所有记录,这就需要用到模糊查询,在模糊查询中需要使用like关键字。
通配符
在SQL语句中可以使用两个通配符:下画线(_)和百分号(%),其中下画线可以代表任意一个字符,百分号可以代表任意多个字符。如下SQL语句将查询 出所有学生中名字以“张”开头的学生。
select * from student table where student name like'张%';
下面的SQL语句将查询出名字为两个字符的所有学生。
select * from student table #下面使用两个下画线代表两个字符 where student name like '__';
转义字符
在某些特殊的情况下,查询的条件里需要使用下画线或百分号,不希望SOL把下画线和百分号当 成通配符使用,这就需要使用转义字符,MySQL使用反斜线()作为转义字符,SQL语句如下: #选出所有名字以下画线开头的学生
select * from student table where studentname like '\_%';
标准SQL语句并没有提供反斜线()的转义字符,而是使用escape关键字显式进行转义。例如 ,为了实现上面功能需要使用如下SQL语句:
#在标准的SQL中选出所有名字以下画线开头的学生 select * from student_table where student_name like '\_%s' escape'\';
is null用于判断某些值是否为空,判断是否为空不要用=null来判断,因为SOL中null=null返回null。如下SOL语句将选择出 student_table表中student_name为null的所有记录。
select * from student_table where student_name is null;
如果where字句后有多个条件需要组合。SQL提供了add和or逻辑运算符来组合两个条件,并提供了not来对逻辑表达式求否。如下SOL语句将选出学生名字为2个字符,且student_id大于3的所有记录。
select * from student_table #使用and来组合多个条件 where student_name like '__' and student_id>3;
下面的SQL语句将选出student_table表中姓名不以下画线开头的所有记录
select * from student_table #使用not对where条件取否 where not student_name like'\_%';
优先级
当使用比较运算符、逻辑运算符来连接表达式时,必须注意这些运算符的优先级。SQL中比较运管符、逻辑运算符的优先级如表13.4所示。
如果SQL代码需要改变优先级的默认顺序,则可以使用括号,括号的优先级比所有的运算符高。如下SQL语句使用括号来改变逻辑运算符的优先级。
select * from student_table #使用括号强制先计算or运算 where (student_id > 3 or student name> '张') and java_teacher > 1;
order by子句
执行查询后的查询结果默认按插入顺序排列;如果需要查询结果按某列值的大小进行排序,则可以使用order by子句。order by子句的语法格式如下:
order by column_name1 [desc], column_name2...
进行排序时默认按升序排列,如果强制按降序排列,则需要在列后使用desc关键字(与之对应的是asc关键字,用不用该关键字的效果完全一样,因为默认是按升序排列)。
上面语法中设定排序列时可采用列名、列序号和列别名。如下SQL语句选出student table表中的所有记录,选出后按java_teacher列的升序排列。
select * from student_table order by java_teacher;
如果需要按多列排序,则每列的asc、desc必须单独设定。如果指定了多个排序列,则第一个排序列是首要排序列,只有当第一列中存在多个相同的值时,第二个排序列才会起作用。如下SQL语句先 按java_teacher列的降序排列,当java_teacher列的值相同时按student_name列的升序排列
select * from student_table order by java_teacher desc, student_name