SELECT {*|<字段名>} [
FROM <表1>,<表2>...
[WHERE <表达式>
[GROUP BY ]
[HAVING [{}...]]
[ORDER BY ]
[LIMIT[,]]
]
SELECT {字段1,字段2,...字段n}
FROM [表或视图]
WHERE[查询条件];
其中,各条子句的含如下:
{*|<字段名>}包含星号通配符选字段列表,表示查询的字段,其中字段列至少包含一个字段名称,如果要查询多个字段,多个字段之间用到逗号隔开,最后一个字段后不要加逗号。
FROM <表1>,<表2>...表1和表2表示查询数据的来源,可以是单个或多个。
WHERE子句是可选项,如果选择该项,将限定查询行必须满足的查询条件。
GROUP BY<字段>,该子句告诉MySQL如果显示查询出来的数据,并按照指定的字段分组。
[ORDER BY
[LIMIT[
创建一张名为student的学生表,表结构如下:
CREATE TABLE student(
s_id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
s_name VARCHAR(10) NOT NULL,
s_age INT NOT NULL ,
s_sex CHAR(2),
s_score DOUBLE NOT NULL,
cls_id INT);
随便插入10条数据
INSERT INTO student(s_id,s_name,s_age,s_sex,s_score,cls_id)VALUES(2018001,'张三',18,'男',86,001),
(2018002,'李四',17,'男',90,001),
(2018003,'王五',22,'男',87,001),
(2018004,'赵柳',19,'女',92,002),
(2018005,'牟琦',18,'女',95,002),
(2018006,'王炸',16,'男',81,002),
(2018007,'闰土',18,'女',83,003),
(2018008,'小红',22,'女',99,003),
(2018009,'小明',25,'男',79,001),
(2018010,'马云',19,'男',90,002);
可以使用最简单的形式也就是通配符“*”来查询所有字段
SELECT * FROM 表名;
SELECT 列名(字段名) FROM 表名;
SELECT 字段名1,字段名2,...,字段名n FROM 表名;
数据库中包含大量的数据,根据特殊要求,可能只需要查询表中的指定数据,即对数据进行过滤,通过WHERE子句可以对数据进行过滤,语法如下
SELECT 字段名1,字段名2,...字段名n
FROM 表名
WHERE 查询条件
SELECT * FROM student WHERE s_id = 2018009;
SELECT * FROM student WHERE s_score < 90;
SELECT * FROM student WHERE s_age IN(17,18,19);
SELECT * FROM student WHERE s_id NOT IN (2018002,2018004,2018008);
SELECT * FROM student WHERE s_score BETWEEN 80 AND 90;
SELECT s_name,s_sex FROM student WHERE s_age BETWEEN 17 AND 20;
百分号“%”通配符,匹配任意长度的字符,甚至包括零字符
SELECT * FROM student WHERE s_name LIKE '王%';
SELECT * FROM student WHERE s_name LIKE '%红';
SELECT * FROM student WHERE s_name LIKE '%m某字%';
下划线通配符“_”,一次只能匹配任意一个字符
SELECT * FROM student WHERE s_name LIKE '王_';
查询某个字段为空的数据,现在现插入一条数据
INSERT INTO student(s_id,s_name,s_age,s_sex,s_score)VALUES(2018011,'奥八马',35,'男',59);
SELECT * FROM student WHERE cls_id IS NULL;
有了IS NULL就自然会有IS NOT NULL
SELECT * FROM student WHERE cls_id IS NOT NULL;
SELECT * FROM student WHERE s_age=18 AND s_score BETWEEN 80 AND 90;
SELECT * FROM student WHERE s_age=18 AND s_sex='女' AND s_score>80;
SELECT * FROM student WHERE s_age<18 OR s_score<80;
SELECT * FROM student WHERE s_age BETWEEN 15 AND 20 OR s_score>90 OR cls_id=2;
查询下班级id
发现有很多重复的cls_id值,有时,出于对数据分析的要求,需要消除重复的记录值,就需要使用到DISTINCT关键字,语法如下
SELECT DISTINCT 字段名 FROM 表名;
SELECT DISTINCT cls_id FROM student;
SELECT * FROM student ORDER BY s_score;
SELECT * FROM student ORDER BY s_score DESC;
SELECT * FROM student ORDER BY s_score,s_name DESC;
分组查询是对数据按照某个字段或多个字段进行分组,MySQL中使用GROUP BY关键字对数据进行分分组,语法如下
[GROUP BY 字段]{HAVING<条件表达式>}
GROUP BY关键字通常和集合函数一起使用,例如MAX(),MIN(),COUNT(),SUM(),AVG()。例如,现在要返回每个班级的学生,就要用到COUNT()函数
SELECT cls_id,COUNT(*) FROM student GROUP BY cls_id;
可以从上表看出,班级3中有2个学生,班级2和班级1中分别有4个学生,班级NULL中有一个学生。
SELECT cls_id,GROUP_CONCAT(s_name) FROM student GROUP BY cls_id;
由结果可以看出,GROUP_CONCAT()函数将每个分组中的名字都显示出来了。
SELECT cls_id,GROUP_CONCAT(s_name) FROM student GROUP BY cls_id HAVING COUNT(s_name)>2;
使用WITH ROLLUP关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的综合,即统计记录数量。
SELECT cls_id,COUNT(*) FROM student GROUP BY cls_id WITH ROLLUP;
SELECT * FROM student GROUP BY cls_id,s_score;
SELECT * FROM student LIMIT 5;
COUNT()函数统计数据表中包含的记录行的总数,或者根据查询结果返回列中包含的数据行数。
SELECT COUNT(*) FROM student;
SELECT COUNT(cls_id) FROM student;
可以看到第十一条记录没有被计入总数
SUM()是一个求总和的函数,返回指定列的总和
SELECT SUM(s_age) as ages FROM student;
SELECT cls_id,SUM(s_score) FROM student GROUP BY cls_id;
AGG()函数通过计算返回的行数和每一行的数据的和,求得指定列数据的平均值
SELECT cls_id,AVG(s_score) FROM student GROUP BY cls_id;
MAX()函数返回指定列中的最大值
SELECT *,MAX(s_score) FROM student;
通过GROUP BY 和 MAX()获得每班成绩最高的学生
SELECT s_name,MAX(s_score) FROM student GROUP BY cls_id;
MIN()返回查询列中的最小值
SELECT *,MIN(s_score) FROM student;
内连接查询(INNER JOIN),使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中连接条件相匹配的数据行,组合成新的记录,也就是说,在内连接查询中,至于满足条件的记录才能在结果关系中。
在这里再创建一个teacher表,两个表用cls_id关联。
CREATE TABLE teacher(
class_id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
t_name VARCHAR(10) NOT NULL,
t_age INT NOT NULL,
t_sex CHAR(2)
);
INSERT INTO teacher(class_id,t_name,t_age,t_sex)VALUES(1,'张老师',35,'男'),
(2,'赵老师',26,'女'),
(3,'王老师',32,'男');
让teacher表做主表,让student做从表,student中的cls_id参照teacher中的class_id做外键,现在添加外键
ALTER TABLE student ADD CONSTRAINT kf_classId FOREIGN KEY (cls_id) REFERENCES teacher(class_id);
SELECT class_id,t_name,t_age,t_sex,s_id,s_name,s_age,s_sex,s_score
FROM teacher,student
WHERE teacher.class_id=student.cls_id;
SELECT class_id,t_name,t_age,t_sex,s_id,s_name,s_age,s_sex,s_score
FROM teacher INNER JOIN student
ON teacher.class_id=student.cls_id;
如果在一个连接查询中,设计到的两个表都是同一个表,这种查询称为自连接查询,自连接查询是一种特殊的内连接,它是指相互连接的表在物理上为同一张表,但是可以在逻辑上分为两张表。
SELECT s1.s_name,s1.cls_id
FROM student AS s1,student AS s2
WHERE s1.s_name=s2.s_name AND s1.cls_id=2;
使用LEFT JOIN
SELECT * FROM teacher LEFT JOIN student ON teacher.t_age=student.s_age;
SELECT * FROM student LEFT JOIN teacher ON teacher.t_age=student.s_age;
使用RIGHT JOIN
SELECT * FROM teacher RIGHT JOIN student ON teacher.t_age=student.s_age;
SELECT * FROM student RIGHT JOIN teacher ON teacher.t_age=student.s_age;
创建两个表
CREATE TABLE t1(num1 INT NOT NULL);
CREATE TABLE t2(num2 INT NOT NULL);
分别向表中插入数据
INSERT INTO t1 VALUES(1),(5),(13),(27);
INSERT INTO t2 VALUES(6),(14),(11),(20);
ANY关键字接在一个比较操作符后面,表示若与子查询返回的任何值比较为TRUE,则返回TRUE。
SELECT num1 FROM t1 WHERE num1>ANY (SELECT num2 FROM t2);
SELECT num1 FROM t1 WHERE num1>ALL (SELECT num2 FROM t2);
EXISTS关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,那么EXISTS的结果为TRUE,此时外层查询语句将进行查询;如果子查询没有返回任何行,那么EXISTS返回的结果为FALSE,此时外层语句将不进行查询。
第一种情况,EXISTS返回TRUE
SELECT * FROM student
WHERE EXISTS
(SELECT s_name FROM student WHERE s_name='张三');
第二种情况,EXISTS返回FALSE,外层查询不进行
SELECT * FROM student
WHERE EXISTS
(SELECT s_age FROM student WHERE s_age=100);
IN关键字进行子查询时,内层查询语句仅仅返回一个数据列,这个数据列李的值将提供给外层查询语句进行比较数据