select 查询的一般格式是
select {[ distinct | all ] columns | *} //1 选择列
from {tables | views | other select} //2 数据来源
where conditions //3 选择条件
group by columns //4 分组
having conditions //5 选择
order by columns //6 排序
一、选择列
- select后面出现的内容可以是from后面的数据来源中的列,可以是*,可以是常量或者T-SQL函数
- 如果列名很长,或者多个表的列名有冲突,可以使用as来定义别名
二、数据来源
- 数据来源可以是表,视图,还可以是其他的select语句(即行集)
- from子句中可以包含连接说明,即inner join, outer join这样的内容。这个内容参见下面的内容
- 可以在from子句中为表,视图,或者其他select语句的结果指定别名,但是不要用as
三、where子句
- 多个条件之间可以用and 或者or连接
- null值查询要使用is null,或者is not null,而不是=null或者<>null
- like是进行模式匹配的一种方式,列的数据类型可以是任何字符或者日期数据。它的否定形式是not like。%和_是通配符,%表示0或多个任意字符,_表示一个任意字符。但是这两个字符如果不出现在like后面的模式中,就是两个普通字符
- text列的where条件只能是like,is null,patindex
- 如果要在like中匹配普通字符%和_,可以使用escape定义一个转义字符,这个转义字符可以随意指定。然后将这个转义字符放在一个通配符或者单引号之前,就表示这个通配符或者单引号是一个普通的字符
- in ,not in, between and, not between and.“between a and b”将会包括a和b在内。in可以转换为一个连接,但是not in不能
- where exists R.当且仅当R非空时,条件exists R为真。 其否定形式是 where not exists R.
- where s <| >| = | <>| >=|<= all/any R.否定形式是在s前对整个表达式加not.
四、连接查询
两张表的连接可以用from子句的ansi连接语法或者where子句中的sql连接语法实现。ansi连接语法格式为from table1 join_type table2 on(conditions) join_type table3 on(conditions)。
连接有等值连接,笛卡尔积(交叉连接),自然连接,theta连接,外链接五种。
假设有三个表,其结构如下:
T_Student表:id, name; 3条数据
T_Course表:id,name; 4条数据
T_SC表:sid, cid,score;10条数据
- 等值连接
select t_student.*, t_sc.*
from t_student inner join t_sc
on (t_student.id = t_sc.sid)
--10条记录,t_sc的记录数目
- 交叉连接(笛卡尔积)
select t_student.*, t_sc.*
from t_student cross join t_Sc
--30条记录,t_student的数目 乘以 t_sc的数目
- 自然连接(等值连接的简化)
select t_student.*, t_sc.cid, t_sc.score
from t_student inner join t_sc
on (t_student.id = t_sc.sid)
--10条记录,t_sc的记录数目。自然连接是一种特殊的等值连接,其特殊之处在于要将结果列中的重复列去掉。
- theta连接
select t_student.*, t_sc.cid, t_sc.score
from t_student inner join t_sc
on (t_student.id = t_sc.sid)
and t_student.id = 'aaa'
- 多表连接,同时也是自然连接
select t_student.name as sname, t_course.name as cname, t_sc.score
from t_student inner join t_sc on (t_student.id = t_sc.sid)
inner join t_course on(t_sc.cid = t_course.id)
--10条记录,t_sc的记录数目
- 外连接
select t_student.*, t_sc.cid, t_sc.score
from t_student left outer join t_sc
on(t_student.id = t_sc.sid)
或者
select t_student.*, t_sc.cid, t_sc.score
from t_student, t_sc
where t_student.id = t_sc.sid(+)
上面的例子是左外连接的示例,对应的还有右外连接。以左外连接为例,实际的查询过程大概是这样的:以t_student为主表,遍历t_student。对于 t_student中的每一条记录(每一个学生),如果t_sc中的记录的sid字段值和该学生id相同,就形成新的记录。如果t_sc中找不到任何一条记录的sid字段值和该学生的id相同,也生成一条新纪录,只不过t_sc表的字段都为null。
- 连接和子查询的比较
如果需要频繁计算聚集数据并将其用在外查询中进行比较,一般用子查询。如果select中的列,来自多个不同的表,一般用连接。
五、group by和having
- select语句中出现的列,都必须出现在group by子句中,除非那一列使用了聚集函数
- having子句是从分组后的结果中筛选行,having的搜索条件在进行分组操作之后应用,所以它必须在group by之后使用
- having子句和where子句的另一个区别在于,它可以出现聚合函数
- where和having中都可以出现比较运算符,between,in,like,all,any
六、order by
order by columns用来对结果集进行排序,按照列顺序,嵌套排序。默认是asc升序,desc是降序。