SQL查詢語句有多種,以下總結下。首先先建三張表用於後面的實驗
-- 学生表,记录学生信息 CREATE TABLE student( sno VARCHAR(10), sname VARCHAR(10), ssex ENUM('男','女'), sage INT, sdept VARCHAR(10), PRIMARY KEY(sno) ); +-----------+-------+------+------+-------+ | sno | sname | ssex | sage | sdept | +-----------+-------+------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | | 201215122 | 刘晨 | 女 | 19 | CS | | 201215123 | 王敏 | 女 | 18 | MA | | 201215125 | 张立 | 男 | 19 | IS | +-----------+-------+------+------+-------+ -- 课程表,记录课程信息,cpno是指当前记录的先行课程的cno CREATE TABLE course( cno INT AUTO_INCREMENT, cname VARCHAR(10), cpno INT, ccredit INT NOT NULL, PRIMARY KEY(cno), FOREIGN KEY(cpno) REFERENCES course(cno) ); +-----------+-------+------+------+-------+ | sno | sname | ssex | sage | sdept | +-----------+-------+------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | | 201215122 | 刘晨 | 女 | 19 | CS | | 201215123 | 王敏 | 女 | 18 | MA | | 201215125 | 张立 | 男 | 19 | IS | +-----------+-------+------+------+-------+ -- 选课记录表,记录选课信息 CREATE TABLE sc ( sno VARCHAR(10), cno INT, grade INT ); +-----------+------+-------+ | sno | cno | grade | +-----------+------+-------+ | 201215121 | 1 | 92 | | 201215121 | 2 | 85 | | 201215121 | 3 | 88 | | 201215122 | 1 | 90 | | 201215122 | 2 | 80 | +-----------+------+-------+
只涉及一張表的查詢語句稱為單表查詢語句,舉個栗子。
SELECT * FROM student; SELECT FROM student WHERE sage>=20;
這些語句只涉及了一張表,所以是單表查詢語句。
與單標查詢對應,涉及多個表的查詢為多表查詢,其中又分為連接查詢、巢狀查詢、 衍生表查詢、集合查詢。
連接查詢是資料庫查詢中最常用的一種查詢語句,是指透過連接欄位和連接條件連接多個表格從而進行查詢,連接查詢又分為小類:等值連接、非等值連接、自然連接、外連接、內連接、自身連接。
當連接條件是等於號(=)時的連接稱之為等值連接,相反,當連接條件不是等於號就是非等值連線。
-- 查询每个学生的选修课情况,连接条件是等于,连接字段是sno SELECT * FROM student,sc WHERE student.sno = sc.sno; +-----------+-------+------+------+-------+-----------+------+-------+ | sno | sname | ssex | sage | sdept | sno | cno | grade | +-----------+-------+------+------+-------+-----------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 1 | 92 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 2 | 85 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 3 | 88 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 1 | 90 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 2 | 80 | +-----------+-------+------+------+-------+-----------+------+-------+
該連接操作的過程是,首先拿出student表中的第一筆記錄,然後根據連接條件和連接字段,與sc表中的所有記錄進行匹配,合適接連接起來形成結果表中的一個元組。然後再拿student表的 第二筆記錄與sc表進行匹配,第三筆記錄...,如此反覆直到取完。這個匹配演算法稱為嵌套循環連接演算法
內連接就是等值連接或非等值連接的另一種寫法,寫法有INNER JOIN ON或CORSS JOIN USING兩種
-- 使用内连接查询每个学生的选修课情况,查询结果和使用上面的等值连接一样。 -- 在MySQL中,INNER可省略,CROSS JOIN= INNER JOIN = INNER SELECT * FROM student INNER JOIN sc ON student.sno=sc.sno; SELECT * FROM student JOIN sc ON student.sno=sc.sno; SELECT * FROM student CROSS JOIN sc USING(sno); +-----------+-------+------+------+-------+-----------+------+-------+ | sno | sname | ssex | sage | sdept | sno | cno | grade | +-----------+-------+------+------+-------+-----------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 1 | 92 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 2 | 85 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 3 | 88 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 1 | 90 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 2 | 80 | +-----------+-------+------+------+-------+-----------+------+-------+
外連接的存在可以彌補內連接僅符合符合條件的元組的缺陷,也就是說,內連接僅能查詢出兩個表中符合連接條件的元組,而外連接可以在某種程度上彌補這種缺陷。外連接分成左外連接(以JOIN關鍵字左邊的表為基準,沒有匹配的記錄則置NULL),右外連接(以JOIN關鍵字右邊的表為基準) ,全外連接(以JOIN關鍵字左右兩邊的表為基準)。其中MySQL不支援全外連接,但可以用集合查詢做到,即將左外連接的查詢結果和右外連接的查詢結果做UNION ALL操作。
-- 左外连接,以左边的表student为基准。 在MySQL中,OUTER关键字在MySQL中可省略 LEFT JOIN=LEFT OUTER JOIN,RIGHT JOIN=RIGHT OUTER JOIN SELECT * FROM student LEFT OUTER JOIN sc ON student.sno=sc.sno; SELECT * FROM student LEFT JOIN sc ON student.sno=sc.sno; +-----------+-------+------+------+-------+-----------+------+-------+ | sno | sname | ssex | sage | sdept | sno | cno | grade | +-----------+-------+------+------+-------+-----------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 1 | 92 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 2 | 85 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 3 | 88 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 1 | 90 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 2 | 80 | | 201215123 | 王敏 | 女 | 18 | MA | NULL | NULL | NULL | | 201215125 | 张立 | 男 | 19 | IS | NULL | NULL | NULL | +-----------+-------+------+------+-------+-----------+------+-------+ -- 右外连接,注意sc和student换了位置 SELECT * FROM sc RIGHT OUTER JOIN student ON student.sno=sc.sno; +-----------+------+-------+-----------+-------+------+------+-------+ | sno | cno | grade | sno | sname | ssex | sage | sdept | +-----------+------+-------+-----------+-------+------+------+-------+ | 201215121 | 1 | 92 | 201215121 | 李勇 | 男 | 20 | CS | | 201215121 | 2 | 85 | 201215121 | 李勇 | 男 | 20 | CS | | 201215121 | 3 | 88 | 201215121 | 李勇 | 男 | 20 | CS | | 201215122 | 1 | 90 | 201215122 | 刘晨 | 女 | 19 | CS | | 201215122 | 2 | 80 | 201215122 | 刘晨 | 女 | 19 | CS | | NULL | NULL | NULL | 201215123 | 王敏 | 女 | 18 | MA | | NULL | NULL | NULL | 201215125 | 张立 | 男 | 19 | IS | +-----------+------+-------+-----------+-------+------+------+-------+ -- 全外连接 SELECT * FROM sc FULL JOIN student ON student.sno=sc.sno; ERROR 1054 (42S22): Unknown column 'sc.sno' in 'on clause' -- 注意是UNION ALL,而非UNION,UNION有个去重效果 SELECT * FROM student LEFT OUTER JOIN sc ON student.sno=sc.sno UNION ALL SELECT * FROM student RIGHT OUTER JOIN sc ON student.sno=sc.sno; +-----------+-------+------+------+-------+-----------+------+-------+ | sno | sname | ssex | sage | sdept | sno | cno | grade | +-----------+-------+------+------+-------+-----------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 1 | 92 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 2 | 85 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 3 | 88 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 1 | 90 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 2 | 80 | | 201215123 | 王敏 | 女 | 18 | MA | NULL | NULL | NULL | | 201215125 | 张立 | 男 | 19 | IS | NULL | NULL | NULL | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 1 | 92 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 2 | 85 | | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | 3 | 88 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 1 | 90 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | 2 | 80 | +-----------+-------+------+------+-------+-----------+------+-------+
在等值連接中去除相同的屬性即為自然連接或稱全自然連接,左自然連接以左表為基準匹配,右自然連接以右表為基準匹配
-- 查询每个学生的选修课情况,自然连接,去除相同的属性sno SELECT student.sno,student.sname,student.ssex,student.sage,student.sdept,sc.cno,sc.grade FROM student,sc WHERE student.sno = sc.sno; SELECT * FROM student NATURAL JOIN sc; +-----------+-------+------+------+-------+------+-------+ | sno | sname | ssex | sage | sdept | cno | grade | +-----------+-------+------+------+-------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | 1 | 92 | | 201215121 | 李勇 | 男 | 20 | CS | 2 | 85 | | 201215121 | 李勇 | 男 | 20 | CS | 3 | 88 | | 201215122 | 刘晨 | 女 | 19 | CS | 1 | 90 | | 201215122 | 刘晨 | 女 | 19 | CS | 2 | 80 | +-----------+-------+------+------+-------+------+-------+ SELECT * FROM student NATURAL LEFT JOIN sc; +-----------+-------+------+------+-------+------+-------+ | sno | sname | ssex | sage | sdept | cno | grade | +-----------+-------+------+------+-------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | 1 | 92 | | 201215121 | 李勇 | 男 | 20 | CS | 2 | 85 | | 201215121 | 李勇 | 男 | 20 | CS | 3 | 88 | | 201215122 | 刘晨 | 女 | 19 | CS | 1 | 90 | | 201215122 | 刘晨 | 女 | 19 | CS | 2 | 80 | | 201215123 | 王敏 | 女 | 18 | MA | NULL | NULL | | 201215125 | 张立 | 男 | 19 | IS | NULL | NULL | +-----------+-------+------+------+-------+------+-------+ -- sc和student位置交换了,仍已student为基准,以为王敏、张立没有选课,所以有NULL字段 SELECT * FROM sc NATURAL RIGHT JOIN student; +-----------+-------+------+------+-------+------+-------+ | sno | sname | ssex | sage | sdept | cno | grade | +-----------+-------+------+------+-------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | 1 | 92 | | 201215121 | 李勇 | 男 | 20 | CS | 2 | 85 | | 201215121 | 李勇 | 男 | 20 | CS | 3 | 88 | | 201215122 | 刘晨 | 女 | 19 | CS | 1 | 90 | | 201215122 | 刘晨 | 女 | 19 | CS | 2 | 80 | | 201215123 | 王敏 | 女 | 18 | MA | NULL | NULL | | 201215125 | 张立 | 男 | 19 | IS | NULL | NULL | +-----------+-------+------+------+-------+------+-------+
顧名思義,自身連結就是一張表,自己和自己連結。
-- '数据库'的先修课信息,连接条件是course1.cno = course2.cpno SELECT * FROM course AS course1,course AS course2 WHERE course1.cno = course2.cpno AND course1.cno = 4 +-----+--------+------+---------+-----+--------+------+---------+ | cno | cname | cpno | ccredit | cno | cname | cpno | ccredit | +-----+--------+------+---------+-----+--------+------+---------+ | 4 | 数据库 | 2 | 4 | 7 | PASCAL | 4 | 4 | +-----+--------+------+---------+-----+--------+------+---------+
首先引入一個查詢區塊的概念,一個SELECT...FROM...WHERE... 形式的SQL語句稱為查詢區塊。當一個查詢區塊的SELECT子句或WHERE子句中巢狀了另一個查詢區塊的查詢語句就稱為巢狀查詢。最外層的查詢稱為外層查詢或父查詢,最內層的查詢稱為內層查詢或子查詢。子查詢用到了父查詢的資料(表格、欄位)的情況稱為相關子查詢,相反,如果沒用到就稱為不相關子查詢。 通常巢狀查詢與IN、ALL、ANY、EXISTS搭配使用。
-- 查询与刘晨在同一个系中的学生(先查出刘晨所在系,再查该系中的学生) -- 内层查询可以独立运行没有依赖于外层,所以是不相关子查询 SELECT * FROM student WHERE sdept IN ( SELECT sdept FROM student WHERE sname='刘晨' ) +-----------+-------+------+------+-------+ | sno | sname | ssex | sage | sdept | +-----------+-------+------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | | 201215122 | 刘晨 | 女 | 19 | CS | +-----------+-------+------+------+-------+ -- 查询选修了‘信息系统’的学生信息(先查出信息系统的课程号cno,再查处所有选课信息,再查出学生信息) -- 同样,也是不相关子查询 SELECT * FROM student WHERE sno IN ( SELECT sno FROM sc WHERE cno IN ( SELECT cno FROM course WHERE cname='信息系统' ) ) +-----------+-------+------+------+-------+ | sno | sname | ssex | sage | sdept | +-----------+-------+------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | +-----------+-------+------+------+-------+ -- 找出每个学生超过自己选修课平均成绩的选课信息(先查出平均成绩,再查出选课信息) -- 内层查询无法独立运行,所以是相关子查询 SELECT * FROM sc AS x WHERE grade >= ( SELECT AVG(grade) FROM sc AS y WHERE x.sno AND y.sno ) +-----------+------+-------+ | sno | cno | grade | +-----------+------+-------+ | 201215121 | 1 | 92 | | 201215121 | 3 | 88 | | 201215122 | 1 | 90 | +-----------+------+-------+
個人認為也是巢狀查詢的一種,但用得比較廣泛,就提出來了。當查詢區塊出現在FROM子句後面時,就稱為派生表查詢。
-- 查询所有选修了cno=1的课程的学生信息 SELECT * FROM student,( SELECT sno FROM SC WHERE cno=1 ) AS tempSC WHERE student.sno = tempSC.sno +-----------+-------+------+------+-------+-----------+ | sno | sname | ssex | sage | sdept | sno | +-----------+-------+------+------+-------+-----------+ | 201215121 | 李勇 | 男 | 20 | CS | 201215121 | | 201215122 | 刘晨 | 女 | 19 | CS | 201215122 | +-----------+-------+------+------+-------+-----------+
涉及UNION、UNION ALL、INTERSECT、EXCEPT的查詢作業就稱為集合查詢。其中,UNION和UNION ALL都會做並集,但UNION會移除重複的記錄。最後,MySQL不支援INTERSECT和EXCEPT。
--查询CS系及年龄不大于19岁的学生(CS系的学生与年龄不大于19岁的学生做并集) SELECT * FROM student WHERE sdept='CS' UNION ALL SELECT * FROM student WHERE sage<=19 +-----------+-------+------+------+-------+ | sno | sname | ssex | sage | sdept | +-----------+-------+------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | | 201215122 | 刘晨 | 女 | 19 | CS | | 201215122 | 刘晨 | 女 | 19 | CS | | 201215123 | 王敏 | 女 | 18 | MA | | 201215125 | 张立 | 男 | 19 | IS | +-----------+-------+------+------+-------+ -- UNION去重 SELECT * FROM student WHERE sdept='CS' UNION SELECT * FROM student WHERE sage<=19 +-----------+-------+------+------+-------+ | sno | sname | ssex | sage | sdept | +-----------+-------+------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | | 201215122 | 刘晨 | 女 | 19 | CS | | 201215123 | 王敏 | 女 | 18 | MA | | 201215125 | 张立 | 男 | 19 | IS | +-----------+-------+------+------+-------+ -- 查询计算机系年龄不大于19岁的学,计算机系的学生与年龄不大于19岁的学生取交集,MySQL不支持INTERSECT操作 SELECT * FROM student WHERE sdept='cs' INTERSECT SELECT * FROM student WHERE sage<=19 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTERSECT SELECT * FROM student WHERE sage<=19' at line 2 -- 用内连接代替 SELECT a.* FROM student AS a INNER JOIN student AS b ON a.sno=b.sno WHERE a.sdept='CS' AND b.sage<=19 +-----------+-------+------+------+-------+ | sno | sname | ssex | sage | sdept | +-----------+-------+------+------+-------+ | 201215122 | 刘晨 | 女 | 19 | CS | +-----------+-------+------+------+-------+ -- 查询计算机系中年龄大于19岁的学生,就是查询计算机系的学生与年龄不大于19岁的学生的差集,MySQL不支持EXCEPT操纵 SELECT * FROM student WHERE sdept='CS' EXCEPT SELECT * FROM student WHERE sage<=19 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXCEPT SELECT * FROM student WHERE sage<=19' at line 2 -- 用外连接或普通连接代替 SELECT a.* FROM student AS a LEFT JOIN student AS b ON a.sno=b.sno WHERE a.sdept='CS' AND b.sage>19 AND b.sno IS NOT NULL SELECT * FROM student WHERE sdept='CS' AND sage>19; +-----------+-------+------+------+-------+ | sno | sname | ssex | sage | sdept | +-----------+-------+------+------+-------+ | 201215121 | 李勇 | 男 | 20 | CS | +-----------+-------+------+------+-------+
以上是mysql中SQL查詢語句分類的範例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!