MySQL基础语法、以及练习

一、基本语法

创建数据库

(test为我们创建数据库的名称)

create database test;

查看数据库

show databases;

选择数据库

use test;

创建表

create table if not exists mytable (
    id int unsigned primary key auto_increment,
    title varchar(100) not null,
    author varchar(40) not null,
    submission_date date
) default charset=utf8;

列出所有表

show tables;

查看某一个表的结构

desc/describe mytable;

mysql> desc mytable;
+-----------------+------------------+------+-----+---------+----------------+
| Field           | Type             | Null | Key | Default | Extra          |
+-----------------+------------------+------+-----+---------+----------------+
| id              | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| title           | varchar(100)     | NO   |     | NULL    |                |
| author          | varchar(40)      | NO   |     | NULL    |                |
| submission_date | date             | YES  |     | NULL    |                |
+-----------------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

删除表(数据)

drop table mytable;   # 直接删除表数据以及表
truncate table mytable;  #  truncate(截断),只删除表数据,不删除表
delete from mytable [where ...];  # 按照条件对表中的数据进行删除 

插入数据(增)

insert mytable(title, author, submission_date) values("MySQL学习", "jing.wang", NOW())
...

mysql> select * from mytable;
+----+------------+-----------+-----------------+
| id | title      | author    | submission_date |
+----+------------+-----------+-----------------+
|  1 | MySQL学习  | jing.wang | 2019-07-26      |
|  2 | 计算机网络  | pei.yang  | 2019-07-26      |
|  3 | 数据结构    | jing.wang | 2019-07-26      |
+----+------------+-----------+-----------------+

删除数据(删)

delete from mytable where author='author_name';

修改数据(改)

update mytable set title='test_titile' where title='MySQL学习';

LIKE子句

mysql> select * from mytable where author like '%wang';
+----+-----------+-----------+-----------------+
| id | title     | author    | submission_date |
+----+-----------+-----------+-----------------+
|  1 | MySQL学习 | jing.wang | 2019-07-26      |
|  3 | 数据结构  | jing.wang | 2019-07-26      |
+----+-----------+-----------+-----------------+
2 rows in set (0.00 sec)


'%a'     //以a结尾的数据
'a%'     //以a开头的数据
'%a%'    //含有a的数据
'_a_'    //三位且中间字母是a的
'_a'     //两位且结尾字母是a的
'a_'     //两位且开头字母是a的

排序

mysql> select * from mytable order by author;
+----+------------+-----------+-----------------+
| id | title      | author    | submission_date |
+----+------------+-----------+-----------------+
|  1 | MySQL学习  | jing.wang | 2019-07-26      |
|  3 | 数据结构   | jing.wang | 2019-07-26      |
|  2 | 计算机网络 | pei.yang  | 2019-07-26      |
+----+------------+-----------+-----------------+

分组

mysql> select author,count(*) from mytable group by author;
+-----------+----------+
| author    | count(*) |
+-----------+----------+
| jing.wang |        2 |
| pei.yang  |        1 |
+-----------+----------+
2 rows in set (0.00 sec)

某员工表staff如下所示:

 id    name  dept  salary  edlevel   hiredate 
  1    张三  开发部  2000     3      2009-10-11
  2    李四  开发部  2500     3      2009-10-01
  3    王五  设计部  2600     5      2010-10-02
  4    王六  设计部  2300     4      2010-10-03
  5    马七  设计部  2100     4      2010-10-06
  6    赵八  销售部  3000     5      2010-10-05
  7    钱九  销售部  3100     7      2010-10-07
  8    孙十  销售部  3500     7      2010-10-06 

列出每个部门最高薪水的结果,sql语句如下:

select dept, max(salary) as MAXIUM from staff group by dept;

查询结果如下:
dept       MAXIMUM
开发部      4500
设计部      2600
销售部      3500

将where子句与group by子句一起使用
分组查询可以在形成组和计算列函数之前具有消除非限定行的标准where子句。必须在group by子句之前指定where子句
查询公司2010年入职的各个部门每个级别里的最高薪水

select dept, edlevel, max(salary) 
from staff 
where hiredate > ' 2010-01-01 '
group by dept, edlevel;


查询结果如下:
dept     edlevel     MAXIMUM
设计部      4         2300
设计部      5         2600
销售部      5         3000
销售部      7         3500

GROUP BY子句之后使用Having子句
可应用限定条件进行分组,以便系统仅对满足条件的组返回结果。因此,在GROUP BY子句后面包含了一个HAVING子句。HAVING类似于WHERE(唯一的差别是WHERE过滤行,HAVING过滤组)AVING支持所有WHERE操作符。
例如,查找雇员数超过2个的部门的最高和最低薪水:

select dept, max(salary), min(salary) 
from staff
group by dept
having count(*) > 2
order by dept;

查询结果如下:
dept     MAXIMUM       MINIMUM
设计部      2600       2100
销售部     3500        3000

查找雇员平均工资大于3000的部门的最高薪水和最低薪水:

select dept, max(salary), min(salary) 
from staff
group by dept
having avg(salary) > 3000
order by dept;

查询结果如下:
dept    MAXIMUM   MINIMUM
销售部          3500       3000

在使用group by的过程中必须注意的一点

在select指定的字段要么就要包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中。

select dept, name, max(salary) as MAXIUM from staff group by dept; (错误的)
其中name不属于group by分组的条件,也不属于聚合函数max等的参数,因此select不能使用name这个属性

Having与Where的区别

  • where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,where条件中不能包含聚组函数,使用where条件过滤出特定的行。

  • having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件过滤出特定的组,也可以使用多个分组标准进行分组。

join用法

JOIN 按照功能大致分为如下三类:

  • INNER JOIN(内连接,或等值连接):获取两个表中字段匹配关系的记录。[默认的join]

  • LEFT JOIN(左连接):获取左表所有记录,即使右表没有对应匹配的记录。

  • RIGHT JOIN(右连接): 与 LEFT JOIN 相反,用于获取右表所有记录,即使左表没有对应匹配的记录。

INNER JOIN

LEFT JOIN

RIGHT JOIN

当前有两张表:

mysql> use RUNOOB;
Database changed
mysql> SELECT * FROM tcount_tbl;
+---------------+--------------+
| runoob_author | runoob_count |
+---------------+--------------+
| 菜鸟教程       | 10           |
| RUNOOB.COM    | 20           |
| Google        | 22           |
+---------------+--------------+
3 rows in set (0.01 sec)
 
mysql> SELECT * from runoob_tbl;
+-----------+---------------+---------------+-----------------+
| runoob_id | runoob_title  | runoob_author | submission_date |
+-----------+---------------+---------------+-----------------+
| 1         | 学习 PHP    | 菜鸟教程         | 2017-04-12      |
| 2         | 学习 MySQL  | 菜鸟教程         | 2017-04-12      |
| 3         | 学习 Java   | RUNOOB.COM      | 2015-05-01      |
| 4         | 学习 Python | RUNOOB.COM      | 2016-03-06      |
| 5         | 学习 C      | FK              | 2017-04-05      |
+-----------+---------------+---------------+-----------------+
5 rows in set (0.01 sec)

INNER JOIN

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count 
FROM runoob_tbl a INNER JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程    | 10             |
| 2           | 菜鸟教程    | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
+-------------+-----------------+----------------+
4 rows in set (0.00 sec)

LEFT JOIN

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count 
FROM runoob_tbl a LEFT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程    | 10             |
| 2           | 菜鸟教程    | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
| 5           | FK              | NULL           |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)

RIGHT JOIN

mysql> SELECT a.runoob_id, a.runoob_author, b.runoob_count FROM runoob_tbl a RIGHT JOIN tcount_tbl b ON a.runoob_author = b.runoob_author;
+-------------+-----------------+----------------+
| a.runoob_id | a.runoob_author | b.runoob_count |
+-------------+-----------------+----------------+
| 1           | 菜鸟教程    | 10             |
| 2           | 菜鸟教程    | 10             |
| 3           | RUNOOB.COM      | 20             |
| 4           | RUNOOB.COM      | 20             |
| NULL        | NULL            | 22             |
+-------------+-----------------+----------------+
5 rows in set (0.01 sec)

二、SQL语句50道题目练习

https://blog.csdn.net/fashion2014/article/details/78826299/

--建表
--学生表
CREATE TABLE `Student`(
    `s_id` VARCHAR(20),
    `s_name` VARCHAR(20) NOT NULL DEFAULT '',
    `s_birth` VARCHAR(20) NOT NULL DEFAULT '',
    `s_sex` VARCHAR(10) NOT NULL DEFAULT '',
    PRIMARY KEY(`s_id`)
);
--课程表
CREATE TABLE `Course`(
    `c_id`  VARCHAR(20),
    `c_name` VARCHAR(20) NOT NULL DEFAULT '',
    `t_id` VARCHAR(20) NOT NULL,
    PRIMARY KEY(`c_id`)
);
--教师表
CREATE TABLE `Teacher`(
    `t_id` VARCHAR(20),
    `t_name` VARCHAR(20) NOT NULL DEFAULT '',
    PRIMARY KEY(`t_id`)
);
--成绩表
CREATE TABLE `Score`(
    `s_id` VARCHAR(20),
    `c_id`  VARCHAR(20),
    `s_score` INT(3),
    PRIMARY KEY(`s_id`,`c_id`)
);
--插入学生表测试数据
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
--课程表测试数据
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');

--教师表测试数据
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');

--成绩表测试数据
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);

Student

Course

teacher

score
  • 1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数

方式1:

select a.*, b.s_score as 01_score, c.s_score as 02_score from
  student a , score b, score c
  where a.s_id = b.s_id
  and a.s_id = c.s_id
  and b.c_id = '01'
  and c.c_id = '02'
  and b.s_score > c.s_score;

方式2:(join on)

select a.*, b.s_score as 01_score, c.s_score as 02_score from
student a 
join score b on a.s_id = b.s_id and b.c_id = '01'
join score c on a.s_id = c.s_id and c.c_id = '02'
where b.s_score > c.s_score;
  • 2、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩
select a.s_id, a.s_name, avg(s_score) as avg_score 
  from student a, score b
  where a.s_id = b.s_id
  group by a.s_id, a.s_name
  having avg(s_score) >= 60;
  • 3、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩 (包括有成绩的和无成绩的)
select a.s_id, a.s_name, avg(b.s_score)
    from student a
    left join score b
    on a.s_id = b.s_id
    group by s_id, s_name
    having avg(b.s_score) < 60
    union
select a.s_id, a.s_name, 0
    from student a
    where a.s_id not in (select distinct s_id from score);
  • 4、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(*)
// 错误的写法,因为这里强调了是所有的学生,所以要包含那些没有成绩的学生
select a.s_id, a.s_name, count(b.c_id), sum(s_score)
    from student a, score b
    where a.s_id = b.s_id
    group by a.s_id, s.s_name;

// 正确写法
select a.s_id, a.s_name, count(b.c_id), sum(s_score)
    from student a
    left join score b on a.s_id = b.s_id
    group by a.s_id;
  • 5、查询"李"姓老师的数量
select count(*) from teacher where t_name like '李%';
  • 6、查询学过"张三"老师授课的同学的信息
// 需要找到张三老师上过课的id,如果那个学生上课的id有前者id集合中,则表示该学生上过张三老师的课
select a.* from student a
    join score b on a.s_id = b.s_id where b.c_id in
    (select c_id from course c
        join teacher d on c.t_id = d.t_id
        where d.t_name = '张三'
    );
  • 7、查询没学过"张三"老师授课的同学的信息 (和上一题类似)
// 先筛选出上个张三老师课程的学生的s_id统计出来,最后只需要将s_id不在前者s_id集合内的学生列举出来信息即可
select a.* from 
    student a where a.s_id not in (
        select a.s_id from student a
            join score b on a.s_id = b.s_id where b.c_id in
            (select c_id from course c
                join teacher d on c.t_id = d.t_id
                where d.t_name = '张三'
            )
    );
  • 8、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息(*)
select a.* from student a, score s1, score s2
    where a.s_id = s1.s_id and a.s_id = s2.s_id and s1.c_id = '01' and s2.c_id = '02';
  • 9、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息(*)
select a.* from student a
    where a.s_id in (select s_id from score where c_id = '01')
    and a.s_id not in (select s_id from score where c_id = '02');
  • 10、查询没有学全所有课程的同学的信息 (*)
select a.* from 
    student a 
    join score b on a.s_id = b.s_id 
    group by b.s_id having count(*) < (select count(c_id) from course);
错误结果

只关心了参加考试的学生,但是存在有学生没有参加考试;

select a.* from 
    student a 
    left join score b on a.s_id = b.s_id 
    group by b.s_id having count(*) < (select count(c_id) from course);
  • 11、查询至少有一门课与学号为"01"的同学所学相同的同学的信息
select distinct a.* from 
    student a join score b on a.s_id = b.s_id 
    where b.c_id in (
    select c.c_id from score c where c.s_id = '01'
    );
  • 12、查询和"01"号的同学学习的课程完全相同的其他同学的信息 (*)
select a.* from student a
    where 
    a.s_id in (
    # 找到与01同学所学课程数相同的s_id的学生
        select s_id from score group by s_id 
        having count(c_id) = (select count(c_id) from score where s_id = '01')
    )
    and
    a.s_id not in (
    # 排除01同学学习了但是有一些同学没有学习
        select distinct s_id from score where c_id not in (
            select c_id from score where s_id = '01'
        )
    )
    and
    # 排除自身
    a.s_id != '01';
  • 13、查询没学过"张三"老师讲授的任一门课程的学生姓名
select a.s_name from student a
    where a.s_id not in (
        # 学过"张三"老师的课
        select distinct s_id from score 
        where c_id in (select c_id from course where t_id = (select t_id from teacher where t_name = '张三'))
    );
  • 14、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩 (*)
select a.s_id,a.s_name,ROUND(AVG(b.s_score)) from 
    student a 
    join score b on a.s_id = b.s_id
    where a.s_id in(
            select s_id from score where s_score<60 GROUP BY s_id having count(s_id)>=2
            )
    GROUP BY a.s_id
  • 15.检索"01"课程分数小于60,按分数降序排列的学生信息
select a.* , b.s_score from student a , score b
    where a.s_id = b.s_id and b.s_score < 60 and b.c_id = '01'
    order by b.s_score desc;

递增是asc

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容