[DB]SQL查询篇

三 29th, 2011

上周接到阿里巴巴的电话面试,结果悲剧了,其原因就是长期泡在window技术平台下面,与阿里的要求不是很符合,但是我却很想去杭州发展,而在杭州,阿里巴巴是个不错的选择。所以我决定开始好好准备下linux与MySQL方面的知识,作为一种知识储备。

基本查询结构:

Select [ALL|DISTINCT] select_list
FROM table_1[,....,table_n]
[JOIN join_condtion]
[WHERE search_condtion]
[GROUP BY group_by_expression]
[HAVING search_condtion]
[ORDER BY order_expression[ASC|DESC]]

上面应该是我们常用的SELECT语句,不知道有多少位同学明白其中这个参数的意义和它们各自的执行顺序呢?

先来看一下各参数意义:

All  : 返回所有的记录
DISTINCT: 查询过程中去掉所有重复的记录
JOIN: 连接查询的关键字
GROUP BY: 用于在聚合函数的查询中分组
HAVING: 用于向GROUP BY子句的结果中添加查询条件
ORDER BY: 对结果集指定排序规则
ASC: 对查询结果进行升序排序
DESC: 对查询结果进行降序排序

其执行的顺序如下:

1. 执行FROM语句.
2. WHERE子句,作用与 1 生成的结果表.
3. GROUP BY子句,作用与步骤2中的结果表.
4. HAVING子句,作用与步骤3中的结果表.
5. 将SELECT子句作用于结果表,选择select_list的列.
6. DISTINCT关键字,删除步骤5中结果表重复行数据.
7. ORDER BY 子句,按指定顺序对结果排序.

常见的基本查询:

SELECT name FROM employee;
SELECT name,phone FROM employee;
SELECT *  FROM employee;
SELECT DISTINCT name,phone FROM employee;
SELECT name as '员工姓名',phone as '联系电话'  FROM employee;

排序和分组的基本用法:

排序 ORDER BY
SELECT *  FROM employee order by id; (默认为升序ASC)
SELECT id, name,phone FROM employee order by id ASC;
SELECT id, name,phone FROM employee order by name DESC;
SELECT id, name,phone FROM employee order by name DESC, id ASC;
SELECT id, name,phone FROM employee order by name DESC, id DESC;
组合 GROUP BY
SELECT id, name,phone FROM employee GROUP BY name; (name中有NULL值可分为一组)
SELECT id, name,phone FROM employee GROUP BY id HAVING id < 100;

条件查询的基本用法:

WHERE 单条件语句查询:
SELECT *  FROM employee WHERE Sex = '女';  (--常见的运算符 <,>,>=,<=,<>,!=,!<,!>,= )

BETWEEN 运算符范围筛选:
SELECT *  FROM employee WHERE age between 20 and 30 ORDER BY age;
SELECT *  FROM employee WHERE birthday between ‘1980-01-01’ and ‘1980-01-01’ ORDER BY birthday;

TOP 子句:
SELECT TOP 3 * FROM employee;    --查询前3条记录
SELECT TOP PERCENT 3 * FROM employee;  --查询前百分之3条记录

NULL 的判断:
SELECT *  FROM employee WHERE Sex IS NULL;
SELECT *  FROM employee WHERE Sex IS NOT NULL;

模糊查询中的常用关键字和通配符:

Like 关键字:
SELECT *  FROM employee WHERE name LIKE '赵_';
SELECT *  FROM employee WHERE name NOT LIKE '赵_';

通配符:
_  , 表示一个字符;
% ,表示任意长度的字符,不受字符个数限制;
[ ] , [ ]指定范围内的任意一个字符;
[^ ], 不在[ ]指定范围内的任意一个字符;

SQL 中基本的运算符:

逻辑运算符:
ANDSELECT name FROM employee WHERE sex = '女' AND no < 10;
ORSELECT name FROM employee WHERE sex = '女' AND no < 10;

IN 运算符:(用于数值,时间,字符串类型的数据)
SELECT name FROM employee WHERE  name  IN ('abc','ac','fr');
SELECT name FROM employee WHERE  name NOT IN ('abc','ac','fr');

数学运算符:+,-,*,/,%

集合查询运算符:
UNION: (从多个表中将多个查询结果结合在一起)
SELECT id,name FROM employee WHERE id < 100
UNION
SELECT stNo, stName FROM student
WHERE stNo < 200
ORDER BY id;
Notice:
1. 两个查询语句中列的数量和列的数据类型必须相互兼容.
2. 最后结果集中的列名来自第一个SELECT语句的列名.
3. 在需要对集合查询结果进行排序时,需要使用第一个查询语句中的列名.
INTERSECT: 交集运算
SELECT id,name FROM employee
WHERE id < 100
INTERSECT
SELECT stNo, stName FROM student
WHERE stNo < 200
Notice: 结果集为4列,取两个查询语句列的数量和

SQL中的表达式:
CAST 表达式:  SELECT no,name,CAST(birthday AS CHAR(11)) FROM employee;
CASE 表达式:
SELECT id , name,娱乐分组 =
CASE
    WHEN birthday > '1981-01-01' AND birthday < '1989-01-01' THEN '青年组'
    WHEN birthday > '1970-01-01' AND birthday < '1981-01-01' THEN '中年组'
    WHEN birthday > '1955-01-01' AND birthday < '1970-01-01' THEN '老年组'
END
FROM employee

上面的查询更多的是单表查询,下面的内容将涉及多表查询:

连接查询:

两表连接:
SELECT student.stNo, student.name, employee.emNo,employee.name
FROM student,employee
WHERE student.stNo = employee.emNo;

多表连接:
SELECT student.stNo, student.name, employee.no,employee.name ,class.name
FROM student,employee,class
WHERE student.stNo = employee.emNo
AND student.classNo = class.clNo

自连接: 使用表的别名实现表与其自身进行连接
SELECT DISTINCT A1.name,A1.mark
FROM  student AS A1, student AS A2
WHERE A1.ID = A2.ID
AND A2.mark < 60;

自然连接: 是指将表中具有相同名称的列自动进行记录匹配, 不能人为地指定哪些列被匹配,只能自                   动判断哪些列,然后进行匹配.
SELECT TNO,tName,tAage,gName,gMark
FROM teachers NATURAL JOIN Groups;
表teachers 和Groups中含有相同列 gid, 上条语句与下语句等价
SELECT S.TNO, S.tName, S.tAage, T.gName, T.gMark
FROM teachers AS S, Groups AS T
WHERE S.gid = T.gid;

内,外,交叉连接:由于内连接篇幅比较长,在此省略,后面会提到。

UNION集合运算:
SELECT stNo,name,mark FROM student
UNION
SELECT A2.tNo,A2.name,A2.mark
FROM teachers AS A2
INNER JOIN Groups AS T
ON A2. tNo = T.gid;

回到内,外,交叉连接:

内连接:  指使用INNER JOIN关键字和比较运算符进行表间某些数据的比操作.
1. 等值连接:  是指连接条件中使用 “=” 运算符
SELECT S.TNO,S.tName,S.tAge, T.gid, T.gName, T.gMark
FROM teachers AS S
INNER JOIN Groups AS T
ON S.gid = T.gid

2. 不等值连接: 是指连接条件中使用除 “=” 之外的运算符
SELECT S.TNO,S.tName,S.tAge, T.gid, T.gName, T.gMark
FROM teachers AS S
INNER JOIN Groups AS T
ON S.gid <> T.gid

3. 使用内连接实现多表连接.
SELECT S.TNO,S.tName,S.tAge, T.gid, T.gName, T.gMark, C.cName
FROM teachers AS S
INNER JOIN Groups AS T
ON S.gid = T.gid
INNER JOIN Class AS C
ON T.gNo = C.cId;

外连接:  外连接是使用OUTER JOIN关键字将两个表连接,与内连接不同的是不仅符合条件的行数据,而且还包含左表(左外连接时的表),右表(),或两边连接表(全外连接表)中所有的数据行.
左外连接:  LEFT OUTER JOIN
右外连接:  RIGHT OUTER JOIN
全外连接:  FULL OUTER JOIN

交叉连接: 使用CROSS JOIN关键字来实现表之间的连接, 返回的结果是两个表的并集,返回两个表所有数据行的笛卡尔积,返回的结果集的数据行数等于两个表行数的乘积.

子查询的使用:

  1. 子查询的SELECT语句包含FROM子句,WHERE子句,HAVING子句和GROUP BY子句,其中WHERE子 句不能省略,其他子句可以省略。
  2. SQL语句中,子查询必须使用括号括起来。
  3. 由关键字IN引入内层子查询的SELECT列表中,只能有一个列名或表达式,还需与外围语句的WHERE子句中名列的列兼容。
  4. 子查询中不能使用ORDER BY子句。
  5. 多表查询中使用子查询:
    SELECT *  FROM employee
    WHERE name = (SELECT name FROM student WHERE name = '刘刚');
    
    IN语句子查询:
    SELECT *  FROM employee
    WHERE sex = ‘女’
    AND name NOT INSELECT name FROM student WHERE name = '刘刚');
    
    EXISTS语句子查询:
    1. EXISTS语句前没有列名,常量或其他表达式.
    2. 由EXISTS引入的子查询的选择列表通常都由星号 * 组成.
    3. 只要EXISTS语句的子查询返回的表中存在记录,WHERE子句就为TRUE,否则为FALSE.
    SELECT *
    FROM employee  AS T
    WHERE EXISTS(SELECT * FROM student WHERE name = T.name)
    ORDER BY employeeid.
    
    UNIQUE子查询: 如果子查询的结果集中有重复记录,则UNIQUE判式的值为FALSE,否则为TRUE.(SQL SERVER并不支持UNIQUE判式)
    SELECT *
    FROM employee
    WHERE UNIQUE(SELECT * FROM student);

    上面只是对常用的SQL查询进行了归纳。有些东西很简单,但在作为承上启下的一种过渡,当有需要的时候可以很快对上面的基本操作进行组合调用,就能达到意想不到效果。





除非注明,本站文章均为原创。本文基于 BY-NC-SA 协议进行授权,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 metaboy(包含链接).

本文链接地址: http://blog.wangyuxiong.com/archives/51114

订阅本站:http://www.wangyuxiong.com/feed

分类: 语言编程         标签: ,

无觅相关文章插件,快速提升流量