最流行的关系型数据库管理系统
,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一评论区评论要资料三个字即可获得MySQL全套资料 !
MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
在我们开始学习MySQL 数据库前,让我们先了解下RDBMS的一些术语
MySQL 为关系型数据库(Relational Database Management System), 这种所谓的
关系型
可以理解为表格
的概念, 一个关系型数据库由一个或数个表格组成, 如图所示的一个表格
MySQL数据表以文件方式存放在磁盘中:
注:
InnoDB
类型数据表只有一个*. frm文件,以及上一级目录的ibdata1文件
MylSAM
类型数据表对应三个文件:
存储位置:因操作系统而异,可查my.ini
decimal(length, precision)用于表示精度确定(小数点后数字的位数确定)的小数类型,length决定了该小数的最大位数,precision用于设置精度(小数点后数字的位数)。
例如: decimal (5,2)表示小数取值范围:999.99~999.99 decimal (5,0)表示: -99999~99999的整数。
各个类别存储空间及取值范围。
非空约束用于确保当前列的值不为空值,非空约束只能出现在表对象的列上。
Null类型特征:所有的类型的值都可以是null,包括int、float 等数据类型
主键约束相当于 唯一约束 + 非空约束 的组合,主键约束列不允许重复,也不允许出现空值。
每个表最多只允许一个主键,建立主键约束可以在列级别创建,也可以在表级别创建。
当创建主键的约束时,系统默认会在所在的列和列组合上建立对应的唯一索引。
外键约束是用来加强两个表(主表和从表)的一列或多列数据之间的连接的,可以保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系。
创建外键约束的顺序是先定义主表的主键,然后定义从表的外键。也就是说只有主表的主键才能被从表用来作为外键使用,被约束的从表中的列可以不是主键,主表限制了从表更新和插入的操作。
自增约束(AUTO_INCREMENT)可以约束任何一个字段,该字段不一定是PRIMARY KEY字段,也就是说自增的字段并不等于主键字段。
但是PRIMARY_KEY约束的主键字段,一定是自增字段,即PRIMARY_KEY 要与AUTO_INCREMENT一起作用于同一个字段。
当插入第一条记录时,自增字段没有给定一个具体值,可以写成DEFAULT/NULL,那么以后插入字段的时候,该自增字段就是从1开始,没插入一条记录,该自增字段的值增加1。当插入第一条记录时,给自增字段一个具体值,那么以后插入的记录在此自增字段上的值,就在第一条记录该自增字段的值的基础上每次增加1。也可以在插入记录的时候,不指定自增字段,而是指定其余字段进行插入记录的操作。
语法:
mysql> net stop mysql
语法:
mysql> net start mysql
语法:mysql -u用户名 -p密码
;
root@243ecf24bd0a:/ mysql -uroot -p123456;
在以上命令行中,mysql 代表客户端命令,-u 后面跟连接的数据库用户,-p 表示需要输入密码。如果数据库设置正常,并输入正确的密码,将看到上面一段欢迎界面和一个 mysql>提示符。
语法:quit
mysql> quit
结果:
对于数据库而言实际上每一张表都表示是一个数据库的对象,而数据库对象指的就是DDL定义的所有操作,例如:表,视图,索引,序列,约束等等,都属于对象的操作,所以表的建立就是对象的建立,而对象的操作主要分为以下三类语法
语法:create database 数据库名字
;
mysql> create database sqltest;
结果:
语法:show databases
;
mysql> show databases;
结果:
可以发现,在上面的列表中除了刚刚创建的 mzc-test,sqltest,外,还有另外 4 个数据库,它们都是安装MySQL 时系统自动创建的,其各自功能如下。
语法:use 数据库名
;
mysql> use mzc-test;
返回Database changed
代表我们已经选择 sqltest 数据库,后续所有操作将在 sqltest 数据库上执行。
有些人可能会问到,连接以后怎么退出。其实,不用退出来,use 数据库后,使用show databases就能查询所有数据库,如果想跳到其他数据库,用use 其他数据库名字。
语法:show tables
;
mysql> show tables;
结果:
语法:drop database 数据库名称
;
mysql> drop database mzc-test;
结果:
注意:删除时,最好用 `` 符号把表明括起来
MyISAM
、InnoDB
、HEAP、 BOB、CSV等
语法:
CREATE TABLE 表名(
#省略代码
)ENGINE= InnoDB;
适用场景:
1. 使用MyISAM:节约空间及响应速度快;不需事务,空间小,以查询访问为主
2. 使用InnoDB:安全性,事务处理及多用户操作数据表;多删除、更新操作,安全性高,事务处理及并发控制
语法:
SHOW ENGINES
结果:
语法:
SHOW VARIABLES LIKE 'storage_engine';
结果:
语法:create table 表名 {列名,数据类型,约束条件};
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`)
);
注意:表名还请遵守数据库的命名规则,这条数据后面要进行删除,所以首字母为大写。
语法:desc 表名
mysql> desc Student;
结果:
虽然 desc 命令可以查看表定义,但是其输出的信息还是不够全面,为了查看更全面的表定义信息,有时就需要通过查看创建表的 SQL 语句来得到,可以使用如下命令实现
语法:show create table 表名 G;
mysql> show create table Student G;
结果:
从上面表的创建 SQL 语句中,除了可以看到表定义以外,还可以看到表的engine(存储引擎)和charset(字符集)等信息。G
选项的含义是使得记录能够按照字段竖着排列,对于内容比较长的记录更易于显示。
语法:drop table 表名
mysql> drop table Student;
结果:
语法:ALTER TABLE 表名 MODIFY [COLUMN] column_definition [FIRST | AFTER col_name]
例如,修改表 student 的 s_name 字段定义,将 varchar(20)改为 varchar(30)
mysql> alter table Student modify s_name varchar(30);
结果:
语法:ALTER TABLE 表名 ADD [COLUMN] [FIRST | AFTER col_name];
例如,表 student 上新增加字段 s_test,类型为 int(3)
mysql> alter table student add column s_test int(3);
结果:
语法:ALTER TABLE 表名 DROP [COLUMN] col_name
例如,将字段 s_test 删除掉
mysql> alter table Student drop column s_test;
结果:
语法:ALTER TABLE 表名 CHANGE [COLUMN] old_col_name column_definition [FIRST|AFTER col_name]
例如,将 s_sex 改名为 s_sex1,同时修改字段类型为 int(4)
mysql> alter table Student change s_sex s_sex1 int(4);
结果:
注意:change 和 modify 都可以修改表的定义,不同的是 change 后面需要写两次列名,不方便。但是 change 的优点是可以修改列名称,modify 则不能。
前面介绍的的字段增加和修改语法(ADD/CNAHGE/MODIFY)中,都有一个可选项first|after column_name,这个选项可以用来修改字段在表中的位置,默认 ADD 增加的新字段是加在表的最后位置,而 CHANGE/MODIFY 默认都不会改变字段的位置。
例如,将新增的字段 s_test 加在 s_id 之后
语法:alter table 表名 add 列名 数据类型 after 列名;
mysql> alter table Student add s_test date after s_id;
结果:
修改已有字段 s_name,将它放在最前面
mysql> alter table Student modify s_name varchar(30) default ‘’ first;
结果:
注意:CHANGE/FIRST|AFTER COLUMN 这些关键字都属于 MySQL 在标准 SQL 上的扩展,在其他数据库上不一定适用。
语法:ALTER TABLE 表名 RENAME [TO] new_tablename
例如,将表 Student 改名为 student
mysql> alter table Student rename student;
结果:
Insert 语句用于向数据库中插入数据
语法:insert into 表名(列名1,列名2,...) values(值1,值2,...)
特点:
案例:
-- 插入学生表测试数据
insert into Student(s_id,s_name,s_birth,s_sex) values('01' , '赵信' , '1990-01-01' , '男');
语法:INSERT INTO 表名 SET 列名 = 值,列名 = 值
案例:
INSERT INTO student SET s_id='02',s_name='德莱厄斯',s_birth='1990-01-01',s_sex='男'
语法:insert into 表名 values(值1,值2,值3),(值4,值5,值6),(值7,值8,值9);
案例:
INSERT INTO student VALUES('03','艾希','1990-01-01','女'),('04','德莱文','1990-08-06','男'),('05','俄洛依','1991-12-01','女');
上面的例子中,值1,值2,值3),(值4,值5,值6),(值7,值8,值9) 即为 Value List,其中每个括号内部的数据表示一行数据,这个例子中插入了三行数据。Insert 语句也可以只给部分列插入数据,这种情况下,需要在 Value List 之前加上 ColumnName List,
例如:
INSERT INTO student(s_name,s_sex) VALUES('艾希','女'),('德莱文','男');
语法:INSERT INTO 表名 SELECT * from 表名;
案例:
INSERT INTO student SELECT * from student1;
注意:
Update 语句一共有两种语法,分别用于更新单表数据和多表数据。
注意:没有 WHERE 条件的 UPDATE 会更新所有值!
语法:UPDATE 表名 SET 字段名 =值 where 字段名=值
案例:
UPDATE student SET s_name ='张三' WHERE s_id ='01'
语法:UPDATE 表名 SET 字段名= 值 WHERE 字段名 in ('值1','值2','值3');
案例:
UPDATE student SET s_name = '李四' WHERE s_id in ('01','02','03');
语法:update 表名 set 字段名 = case 字段名 when 值1 then '值' when 值2 then '值' when 值3 then '值' end where s_id in (值1,值2,值3)
案例:
update student set s_name = case s_id when 01 then '小王' when 02 then '小周' when 03 then '老周' end where s_id in (01,02,03)
案例 2:
UPDATE student SET s_birth = CASE s_name
WHEN '小王' THEN
'2019-01-20'
WHEN '小周' THEN
'2019-01-22'
END WHERE s_name IN ('小王','小周');
语法:DELETE FROM 表名 WHERE 列名=值
案例:
DELETE FROM student WHERE s_id='09'
与 SELECT 语句不同的是,DELETE 语句中不能使用 GROUP BY、 HAVING 和 ORDER BY 三类子句,而只能使用WHERE 子句。
原因很简单, GROUP BY 和 HAVING 是从表中选取数据时用来改变抽取数据形式的, 而 ORDER BY 是用来指定取得结果显示顺序的。因此,在删除表中数据 时它们都起不到什么作用。`
语法:TRUNCATE 表名;
注意:全部删除,内存无痕迹,如果有自增会重新开始编号。
与 DELETE 不同的是,TRUNCATE 只能删除表中的全部数据,而不能通过 WHERE 子句指定条件来删除部分数据。也正是因为它不能具体地控制删除对象, 所以其处理速度比 DELETE 要快得多。实际上,DELETE 语句在 DML 语句中也 属于处理时间比较长的,因此需要删除全部数据行时,使用 TRUNCATE 可以缩短 执行时间。
案例:
TRUNCATE student1;
语法:select 列名 from 表名 where 列名 =值
where的作用:
搜索条件的组成:
注意:数值数据类型的记录之间才能进行算术运算,相同数据类型的数据之间才能进行比较。
表数据
案例 1(AND):
SELECT * FROM student WHERE s_name ='小王' AND s_sex='男'
案例 2(OR):
SELECT * FROM student WHERE s_name ='崔丝塔娜' OR s_sex='男'
案例 3(NOT):
SELECT * FROM student WHERE NOT s_name ='崔丝塔娜'
案例 4(IS NULL):
SELECT * FROM student WHERE s_name IS NULL;
案例 5(IS NOT NULL):
SELECT * FROM student WHERE s_name IS NOT NULL;
案例 6(BETWEEN):
SELECT * FROM student WHERE s_birth BETWEEN '2019-01-20' AND '2019-01-22'
案例 7(LINK):
SELECT * FROM student WHERE s_name LIKE '小%'
案例 8(IN):
SELECT * FROM student WHERE s_name IN ('小王','小周')
案例:
SELECT s_name as `name` FROM student
案例
SELECT DISTINCT * FROM student
指定字段
星号表示所有字段
手动指定需要查询的字段
SELECT DISTINCT s_name,s_birth FROM student
语法:
select 字段名 from 表名 group by 字段名称;
SELECT COUNT(*)FROM student GROUP BY s_sex;
SELECT s_name,s_sex,COUNT(*) FROM student GROUP BY s_name,s_sex;
我们如果要查询男生或者女生,人数大于4的性别
SELECT s_sex as 性别,count(s_id) AS 人数 FROM student GROUP BY s_sex HAVING COUNT(s_id)>4
语法:
select * from 表名 order by 字段名;
SELECT * FROM student ORDER BY s_id DESC;
SELECT * FROM student ORDER BY s_id DESC, s_birth ASC;
语法1:
select * from table_name limit 个数;
语法2:
select * from table_name limit 起始位置,个数;
案例:
查询前三条数据
SELECT * FROM student LIMIT 3;
从第三条开始 查询3条
SELECT * FROM student LIMIT 2,3;
注意:起始位置 从0开始
经典的使用场景:分页显示
将一个查询语句的结果作为另一个查询语句的条件或是数据来源, 当我们一次性查不到想要数据时就需要使用子查询。
SELECT
*
FROM
score
WHERE
s_id =(
SELECT
s_id
FROM
student
WHERE
s_name = ‘赵信’)
子查询的思路:
要分析 查到最终的数据 到底有哪些步骤
根据步骤写出对应的sql语句
把上一个步骤的sql语句丢到下一个sql语句中作为条件
SELECT
*
FROM
score
WHERE
s_id IN (
SELECT
s_id
FROM
student
WHERE
s_sex = ‘男’)
语法:
select * from 表1 inner join 表2;
在外连接查询中不能使用where 关键字 必须使用on专门来做表的对应关系
当成功创建用户账户后,还不能执行任何操作,需要为该用户分配适当的访问权限。可以使用SHOW GRANTS FOR
语句来查询用户的权限。
例如:
mysql> SHOW GRANTS FOR test;
+-------------------------------------------+
| Grants for test@% |
+-------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' |
+-------------------------------------------+
1 row in set (0.00 sec)
GRANT
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
TO user [auth_option] [, user [auth_option]] ...
[REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
[WITH {GRANT OPTION | resource_option} ...]
GRANT PROXY ON user
TO user [, user] ...
[WITH GRANT OPTION]
object_type: {
TABLE
| FUNCTION
| PROCEDURE
}
priv_level: {
*
| *.*
| db_name.*
| db_name.tbl_name
| tbl_name
| db_name.routine_name
}
user:
(see Section 6.2.4, “Specifying Account Names”)
auth_option: {
IDENTIFIED BY 'auth_string'
| IDENTIFIED WITH auth_plugin
| IDENTIFIED WITH auth_plugin BY 'auth_string'
| IDENTIFIED WITH auth_plugin AS 'auth_string'
| IDENTIFIED BY PASSWORD 'auth_string'
}
tls_option: {
SSL
| X509
| CIPHER 'cipher'
| ISSUER 'issuer'
| SUBJECT 'subject'
}
resource_option: {
| MAX_QUERIES_PER_HOUR count
| MAX_UPDATES_PER_HOUR count
| MAX_CONNECTIONS_PER_HOUR count
| MAX_USER_CONNECTIONS count
}
授予数据库权限时,priv_type
可以指定为以下值:
授予表权限时,priv_type
可以指定为以下值:
priv_type
的值只能指定为SELECT、INSERT和UPDATE,同时权限的后面需要加上列名列表(column-list)。priv_type
的值指定为CREATE USER权限,具备创建用户、删除用户、重命名用户和撤消所有特权,而且是全局的。有ON,是授予权限,无ON,是授予角色。如:
– 授予数据库db1的所有权限给指定账户
GRANT ALL ON db1.* TO ‘user1’@‘localhost’;
– 授予角色给指定的账户
GRANT ‘role1’, ‘role2’ TO ‘user1’@‘localhost’, ‘user2’@‘localhost’;
指定权限级别的值有以下几类格式:
'user_name'@'host_name'
user表中host列的默认值
host
说明
%
匹配所有主机
localhost
localhost不会被解析成IP地址,直接通过UNIXsocket连接
127.0.0.1
会通过TCP/IP协议连接,并且只能在本机访问
::1
::1就是兼容支持ipv6的,表示同ipv4的127.0.0.1
host_name格式有以下几种:
参数
说明
MAX_QUERIES_PER_HOUR count
每小时最大查询数
MAX_UPDATES_PER_HOUR count
每小时最大更新数
MAX_CONNECTIONS_PER_HOUR count
每小时连接次数
MAX_USER_CONNECTIONS count
用户最大连接数
若要权限生效,需要执行以下语句:
FLUSH PRIVILEGES;
REVOKE
语法和GRANT
语句的语法格式相似,但具有相反的效果
REVOKE
priv_type [(column_list)]
[, priv_type [(column_list)]] …
ON [object_type] priv_level
FROM user [, user] …
REVOKE ALL [PRIVILEGES], GRANT OPTION
FROM user [, user] …
REVOKE PROXY ON user
FROM user [, user] …
若要使用REVOKE语句,必须拥有MySQL数据库的全局CREATE USER权限或UPDATE权限;
第一种语法格式用于回收指定用户的某些特定的权限,第二种回收指定用户的所有权限;
什么是事物?
事务的ACID属性
原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态
隔离性:一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰
持久性:一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
分类
隐式事务:事务没有明显的开启和结束的标记(比如insert,update,delete语句)
显式事务:事务具有明显的开启和结束的标记(autocommit变量设置为0)
默认开启事务
SET autocommit = 0 ;
COMMIT;
ROLLBACK ;
select @@tx_isolation;
set session transaction isolation level read uncommitted;
set global transaction isolation level read committed ;
(这里使用 Navicat Premium 15 工具进行演示)
因为内容太多了这里只演示一些常用的
对数值型的数据进行指定的数学运算,如abs()函数可以获得给定数值的绝对值,round()函数可以对给定的数值进行四舍五入。
作用:返回 number 的绝对值
SELECT
ABS(s_score)
FROM
score;
ABS(-86) 返回:86
number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
例1:pi() 返回:3.141592653589793
例2:pi(2) 返回:6.283185307179586
作用:计算圆周率及其倍数
作用:前者返回最接近于x的整数,即对x进行四舍五入;后者返回最接近x的数,其值保留到小数点后面y位,若y为负值,则将保留到x到小数点左边y位
SELECT ROUND(345222.9)
nExp个位数 =0:表示当前小数点的位置
作用:计算字符串字符个数
SELECT CHAR_LENGTH(‘这是一个十二个字的字符串’);
作用:返回连接参数产生的字符串,一个或多个待拼接的内容,任意一个为NULL则返回值为NULL
SELECT CONCAT(‘拼接’,‘测试’);
作用:返回多个字符串拼接之后的字符串,每个字符串之间有一个x
SELECT CONCAT_WS(‘-’,‘测试’,‘拼接’,‘WS’)
作用:返回字符串s1,其子字符串起始于位置x,被字符串s2取代len个字符
SELECT INSERT(‘测试字符串替换’,2,1,‘牛’);
作用:前两者将str中的字母全部转换成小写,后两者将字符串中的字母全部转换成大写
SELECT LOWER(‘JHGYTUGHJGG’),LCASE(‘HKJHKJHKJHKJ’);
SELECT UPPER('aaaaaa'),UCASE('vvvvv');
作用:前者返回字符串s从最左边开始的n个字符,后者返回字符串s从最右边开始的n个字符
SELECT LEFT(‘左边开始’,2),RIGHT(‘右边开始’,2);
作用:前者返回s1,其左边由字符串s2填补到len字符长度,假如s1的长度大于len,则返回值被缩短至len字符;前者返回s1,其右边由字符串s2填补到len字符长度,假如s1的长度大于len,则返回值被缩短至len字符
SELECT LEFT(‘左边开始’,2),RIGHT(‘右边开始’,2);
作用:前者返回字符串s,其左边所有空格被删除;后者返回字符串s,其右边所有空格被删除
SELECT LTRIM(’ 左边开始’),RTRIM(’ 右边开始 ');
作用:返回字符串s删除了两边空格之后的字符串
SELECT TRIM(’ 是是 ');
作用:返回一个由重复字符串s组成的字符串,字符串s的数目等于n
SELECT REPEAT(‘测试’,5);
作用:返回一个由n个空格组成的字符串
SELECT SPACE(20);
作用:若s1和s2中所有的字符串都相同,则返回0;根据当前分类次序,第一个参数小于第二个则返回-1,其他情况返回1
SELECT STRCMP(‘我我我’,‘我我我’);
SELECT STRCMP('我我我','是是是');
作用:两个函数作用相同,从字符串s中返回一个第n个字符开始、长度为len的字符串
SELECT SUBSTRING(‘测试测试’,2,2);
SELECT MID('测试测试',2,2);
作用:三个函数作用相同,返回子字符串str1在字符串str中的开始位置(从第几个字符开始)
SELECT LOCATE(‘字’,‘获取字符串的位置’);
作用:将字符串s反转
SELECT REVERSE(‘字符串反转’);
作用:返回第N个字符串
SELECT ELT(2,‘字符串反转’,‘sssss’);
当前时间
作用:这四个函数作用相同,返回当前日期和时间值,格式为"YYYY_MM-DD HH:MM:SS"或"YYYYMMDDHHMMSS",具体格式根据函数用在字符串或数字语境中而定
SELECT CURRENT_TIMESTAMP()
SELECT LOCALTIME()
SELECT NOW()
SELECT SYSDATE()
作用:前者返回一个格林尼治标准时间1970-01-01 00:00:00到现在的秒数,后者返回一个格林尼治标准时间1970-01-01 00:00:00到指定时间的秒数
SELECT UNIX_TIMESTAMP()
前者返回当前UTC(世界标准时间)日期值,其格式为"YYYY-MM-DD"或"YYYYMMDD",后者返回当前UTC时间值,其格式为"YYYY-MM-DD"或"YYYYMMDD"。具体使用哪种取决于函数用在字符串还是数字语境中
SELECT UTC_DATE()
SELECT UTC_TIME()
作用:前者返回指定日期中的月份,后者返回指定日期中的月份的名称
SELECT MONTH(NOW())
SELECT MONTHNAME(NOW())
计算日期d是一年中的第几周
SELECT WEEK(NOW())
作用:前者返回d是一年中的第几天,后者返回d是一月中的第几天
SELECT DAYOFYEAR(NOW())
SELECT DAYOFMONTH(NOW())
作用: YEAR(date)返回指定日期对应的年份,范围是1970~2069
;QUARTER(date)返回date对应一年中的季度,范围是1~4
;MINUTE(time)返回time对应的分钟数,范围是0~59
;SECOND(time)返回制定时间的秒值
SELECT YEAR(NOW())
SELECT QUARTER(NOW())
SELECT MINUTE(NOW())
SELECT SECOND(NOW())
作用:返回以转换为秒的time参数,转换公式为"3600_小时 + 60_分钟 + 秒"
SELECT TIME_TO_SEC(NOW())
作用:和TIME_TO_SEC(time)互为反函数,将秒值转换为时间格式
SELECT SEC_TO_TIME(530)
作用:查看MySQL版本号
SELECT VERSION()
作用:查看当前用户的连接数
SELECT CONNECTION_ID()
作用:查看当前被MySQL服务器验证的用户名和主机的组合,一般这几个函数的返回值是相同的
SELECT USER()
SELECT CURRENT_USER()
SELECT SYSTEM_USER()
SELECT SESSION_USER()
作用:查看字符串str使用的字符集
SELECT CHARSET(555)
作用:查看字符串排列方式
SELECT COLLATION(‘sssfddsfds’)
作用:从原明文密码str计算并返回加密后的字符串密码,注意这个函数的加密是单向的(不可逆),因此不应将它应用在个人的应用程序中而应该只在MySQL服务器的鉴定系统中使用
SELECT PASSWORD(‘mima’)
作用:为字符串算出一个MD5 128比特校验和,改值以32位十六进制数字的二进制字符串形式返回
SELECT MD5(‘mima’)
作用:使用pswd_str作为密码,加密str
SELECT ENCODE(‘fdfdz’,‘mima’)
作用:使用pswd_str作为密码,解密加密字符串crypt_str,crypt_str是由ENCODE函数返回的字符串
SELECT DECODE(‘fdfdz’,‘mima’)
作用:将数字x格式化,并以四舍五入的方式保留小数点后n位,结果以字符串形式返回
SELECT FORMAT(446.454,2)
更多用法还请参考:http://www.geezn.com/documents/gez/help/117555-1355219868404378.html
-- 学生表
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)
s_id = 学生编号,s_name = 学生姓名,s_birth = 出生年月,s_sex = 学生性别
课程表(course)
c_id = 课程编号,c_name = 课程名称,t_id = 教师编号
教师表(teacher)
t_id = 教师编号,t_name = 教师姓名
成绩表(score)
s_id = 学生编号,c_id = 课程编号,s_score = 分数
SELECT
st.*,
sc.s_score AS '语文',
sc2.s_score '数学'
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
AND sc.c_id = '01'
LEFT JOIN score sc2 ON sc2.s_id = st.s_id
AND sc2.c_id = '02'
SELECT
st.*,
s.s_score AS 数学,
s2.s_score AS 语文
FROM
student st
LEFT JOIN score s ON s.s_id = st.s_id
AND s.c_id = '01'
LEFT JOIN score s2 ON s2.s_id = st.s_id
AND s2.c_id = '02'
WHERE
s.s_score < s2.s_score
SELECT
st.s_id AS '学生编号',
st.s_name AS '学生姓名',
AVG( s.s_score ) AS avgScore
FROM
student st
LEFT JOIN score s ON st.s_id = s.s_id
GROUP BY
st.s_id
HAVING
avgScore >= 60
(包括有成绩的和无成绩的)
SELECT
st.s_id AS ‘学生编号’,
st.s_name AS ‘学生姓名’,(
CASE
WHEN ROUND( AVG( sc.s_score ), 2 ) IS NULL THEN
0 ELSE ROUND( AVG( sc.s_score ), 2 )
END
)
FROM
student st
LEFT JOIN score sc ON st.s_id = sc.s_id
GROUP BY
st.s_id
HAVING
AVG( sc.s_score )< 60
OR AVG( sc.s_score ) IS NULL
SELECT
st.s_id AS '学生编号',
st.s_name AS '学生姓名',
COUNT( sc.c_id ) AS '选课总数',
sum( CASE WHEN sc.s_score IS NULL THEN 0 ELSE sc.s_score END ) AS '总成绩'
FROM
student st
LEFT JOIN score sc ON st.s_id = sc.s_id
GROUP BY
st.s_id
SELECT COUNT(t_id) FROM teacher WHERE t_name LIKE '流%'
SELECT
st.*
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
LEFT JOIN course cs ON cs.c_id = sc.c_id
LEFT JOIN teacher tc ON tc.t_id = cs.t_id
WHERE tc.t_name = '流浪法师'
-- 查询流浪法师教的课
SELECT
cs.*
FROM
course cs
LEFT JOIN teacher tc ON tc.t_id = cs.t_id
WHERE
tc.t_name = '流浪法师'
-- 查询有流浪法师课程成绩的学生id
SELECT
sc.s_id
FROM
score sc
WHERE
sc.c_id IN (
SELECT
cs.c_id
FROM
course cs
LEFT JOIN teacher tc ON tc.t_id = cs.t_id
WHERE
tc.t_name = '流浪法师')
-- 取反,查询没有学过流浪法师课程的同学信息
SELECT
st.*
FROM
student st
WHERE
st.s_id NOT IN (
SELECT
sc.s_id
FROM
score sc
WHERE
sc.c_id IN ( SELECT cs.c_id FROM course cs LEFT JOIN teacher tc ON tc.t_id = cs.t_id WHERE tc.t_name = '流浪法师' )
)
方法 1
– 查询学过编号为01课程的同学id
SELECT
st.s_id
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course cs ON cs.c_id = sc.c_id
AND cs.c_id = ‘01’;
– 查询学过编号为02课程的同学id
SELECT
st2.s_id
FROM
student st2
INNER JOIN score sc2 ON sc2.s_id = st2.s_id
INNER JOIN course cs2 ON cs2.c_id = sc2.c_id
AND cs2.c_id = ‘02’;
– 查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息
SELECT
st.*
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course cs ON cs.c_id = sc.c_id
AND sc.c_id = ‘01’
WHERE
st.s_id IN (
SELECT
st2.s_id
FROM
student st2
INNER JOIN score sc2 ON sc2.s_id = st2.s_id
INNER JOIN course cs2 ON cs2.c_id = sc2.c_id
AND cs2.c_id = ‘02’
);
方法 2
SELECT
a.*
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’;
SELECT
st.s_id
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course cs ON cs.c_id = sc.c_id
AND cs.c_id = '01'
WHERE
st.s_id NOT IN (
SELECT
st.s_id
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course cs ON cs.c_id = sc.c_id
AND cs.c_id = '02'
);
方法 1
SELECT
*
FROM
student
WHERE
s_id NOT IN (
SELECT
st.s_id
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
AND sc.c_id = ‘01’
WHERE
st.s_id IN (
SELECT
st.s_id
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
AND sc.c_id = ‘02’
WHERE
st.s_id
)
AND st.s_id IN (
SELECT
st.s_id
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
AND sc.c_id = ‘03’
WHERE
st.s_id
)
);
方法 2
SELECT
a.*
FROM
student a
LEFT JOIN score b ON a.s_id = b.s_id
GROUP BY
a.s_id
HAVING
COUNT( b.c_id ) != ‘3’;
SELECT DISTINCT
st.*
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
WHERE
sc.c_id IN ( SELECT sc2.c_id FROM student st2 LEFT JOIN score sc2 ON sc2.s_id = st2.s_id WHERE st2.s_id = '01' );
SELECT
st.*
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
GROUP BY
st.s_id
HAVING
GROUP_CONCAT( sc.c_id )=(
SELECT
GROUP_CONCAT( sc2.c_id )
FROM
student st2
LEFT JOIN score sc2 ON sc2.s_id = st2.s_id
WHERE
st2.s_id = '01'
);
SELECT
*
FROM
student
WHERE
s_id NOT IN (
SELECT
sc.s_id
FROM
score sc
INNER JOIN course cs ON cs.c_id = sc.c_id
INNER JOIN teacher t ON t.t_id = cs.t_id
AND t.t_name = '邪恶小法师');
SELECT
st.s_id AS '学号',
st.s_name AS '姓名',
AVG( sc.s_score ) AS '平均成绩'
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
WHERE
sc.s_id IN (
SELECT
sc.s_id
FROM
score sc
WHERE
sc.s_score < 60
OR sc.s_score IS NULL
GROUP BY
sc.s_id
HAVING
COUNT( 1 )>= 2
)
GROUP BY
st.s_id
SELECT
st.*
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
AND sc.c_id = '01'
AND sc.s_score < '60'
ORDER BY
sc.s_score DESC;
SELECT
st.*
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
WHERE
sc.c_id = '01'
AND sc.s_score < '60'
ORDER BY
sc.s_score DESC;
方法 1
SELECT
st.*,
AVG( sc4.s_score ) AS ‘平均分’,
sc.s_score AS ‘语文’,
sc2.s_score AS ‘数学’,
sc3.s_score AS ‘英语’
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
AND sc.c_id = ‘01’
LEFT JOIN score sc2 ON sc2.s_id = st.s_id
AND sc2.c_id = ‘02’
LEFT JOIN score sc3 ON sc3.s_id = st.s_id
AND sc3.c_id = ‘03’
LEFT JOIN score sc4 ON sc4.s_id = st.s_id
GROUP BY
st.s_id
ORDER BY
AVG( sc4.s_score ) DESC;
方法 2
SELECT
st.*,
( CASE WHEN AVG( sc4.s_score ) IS NULL THEN 0 ELSE AVG( sc4.s_score ) END ) AS ‘平均分’,
( CASE WHEN sc.s_score IS NULL THEN 0 ELSE sc.s_score END ) AS ‘语文’,
( CASE WHEN sc2.s_score IS NULL THEN 0 ELSE sc2.s_score END ) AS ‘数学’,
( CASE WHEN sc3.s_score IS NULL THEN 0 ELSE sc3.s_score END ) AS ‘英语’
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
AND sc.c_id = ‘01’
LEFT JOIN score sc2 ON sc2.s_id = st.s_id
AND sc2.c_id = ‘02’
LEFT JOIN score sc3 ON sc3.s_id = st.s_id
AND sc3.c_id = ‘03’
LEFT JOIN score sc4 ON sc4.s_id = st.s_id
GROUP BY
st.s_id
ORDER BY
AVG( sc4.s_score ) DESC;
以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
SELECT
cs.c_id,
cs.c_name,
MAX( sc1.s_score ) AS ‘最高分’,
MIN( sc2.s_score ) AS ‘最低分’,
AVG( sc3.s_score ) AS ‘平均分’,
((
SELECT
COUNT( s_id )
FROM
score
WHERE
s_score >= 60
AND c_id = cs.c_id
)/(
SELECT
COUNT( s_id )
FROM
score
WHERE
c_id = cs.c_id
)) AS ‘及格率’,
((
SELECT
COUNT( s_id )
FROM
score
WHERE
s_score >= 70
AND s_score < 80
AND c_id = cs.c_id
)/(
SELECT
COUNT( s_id )
FROM
score
WHERE
c_id = cs.c_id
)) AS ‘中等率’,
((
SELECT
COUNT( s_id )
FROM
score
WHERE
s_score >= 80
AND s_score < 90
AND c_id = cs.c_id
)/(
SELECT
COUNT( s_id )
FROM
score
WHERE
c_id = cs.c_id
)) AS ‘优良率’,
((
SELECT
COUNT( s_id )
FROM
score
WHERE
s_score >= 90
AND c_id = cs.c_id
)/(
SELECT
COUNT( s_id )
FROM
score
WHERE
c_id = cs.c_id
)) AS ‘优秀率’
FROM
course cs
LEFT JOIN score sc1 ON sc1.c_id = cs.c_id
LEFT JOIN score sc2 ON sc2.c_id = cs.c_id
LEFT JOIN score sc3 ON sc3.c_id = cs.c_id
GROUP BY
cs.c_id;
mysql没有rank函数
加@score是为了防止用union all 后打乱了顺序
SELECT
c1.s_id,
c1.c_id,
c1.c_name,
@score := c1.s_score,
@i := @i + 1
FROM
(
SELECT
c.c_name,
sc.*
FROM
course c
LEFT JOIN score sc ON sc.c_id = c.c_id
WHERE
c.c_id = “01”
ORDER BY
sc.s_score DESC
) c1,
( SELECT @i := 0 ) a UNION ALL
SELECT
c2.s_id,
c2.c_id,
c2.c_name,
c2.s_score,
@ii := @ii + 1
FROM
(
SELECT
c.c_name,
sc.*
FROM
course c
LEFT JOIN score sc ON sc.c_id = c.c_id
WHERE
c.c_id = “02”
ORDER BY
sc.s_score DESC
) c2,
( SELECT @ii := 0 ) aa UNION ALL
SELECT
c3.s_id,
c3.c_id,
c3.c_name,
c3.s_score,
@iii := @iii + 1
FROM
(
SELECT
c.c_name,
sc.*
FROM
course c
LEFT JOIN score sc ON sc.c_id = c.c_id
WHERE
c.c_id = “03”
ORDER BY
sc.s_score DESC
) c3;
SET @iii = 0;
SELECT
st.s_id,
st.s_name,
( CASE WHEN sum( sc.s_score ) IS NULL THEN 0 ELSE SUM( sc.s_score ) END )
FROM
student st
LEFT JOIN score sc ON st.s_id = sc.s_id
GROUP BY
st.s_id
ORDER BY
SUM( sc.s_score ) DESC
SELECT
t.t_id,
t.t_name,
AVG( sc.s_score )
FROM
teacher t
LEFT JOIN course c ON c.t_id = t.t_id
LEFT JOIN score sc ON sc.c_id = c.c_id
GROUP BY
t.t_id
ORDER BY
AVG( sc.s_score ) DESC
SELECT
a.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_id,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON sc.c_id = c.c_id
AND c.c_id = '01'
ORDER BY
sc.s_score DESC
LIMIT 1,
2
) a UNION ALL
SELECT
b.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_id,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_id = '02'
ORDER BY
sc.s_score DESC
LIMIT 1,
2
) b UNION ALL
SELECT
c.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_id,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_id = '03'
ORDER BY
sc.s_score DESC
LIMIT 1,
2
) c;
SELECT
c.c_id,
c.c_name,
(
SELECT
COUNT( 1 )
FROM
score sc
WHERE
sc.c_id = c.c_id
AND sc.s_score <= 100 AND sc.s_score > 80
)/(
SELECT
COUNT( 1 )
FROM
score sc
WHERE
sc.c_id = c.c_id
) AS '100-85',
((
SELECT
COUNT( 1 )
FROM
score sc
WHERE
sc.c_id = c.c_id
AND sc.s_score <= 85 AND sc.s_score > 70
)/(
SELECT
COUNT( 1 )
FROM
score sc
WHERE
sc.c_id = c.c_id
)) AS '85-70',
((
SELECT
COUNT( 1 )
FROM
score sc
WHERE
sc.c_id = c.c_id
AND sc.s_score <= 70 AND sc.s_score > 60
)/(
SELECT
COUNT( 1 )
FROM
score sc
WHERE
sc.c_id = c.c_id
)) AS '70-60',
((
SELECT
COUNT( 1 )
FROM
score sc
WHERE
sc.c_id = c.c_id
AND sc.s_score <= 60 AND sc.s_score >= 0
)/(
SELECT
COUNT( 1 )
FROM
score sc
WHERE
sc.c_id = c.c_id
)) AS '85-70'
FROM
course c
ORDER BY
c.c_id
SET @i = 0;
SELECT
a.*,
@i := @i + 1
FROM
(
SELECT
st.s_id,
st.s_name,
round( CASE WHEN AVG( sc.s_score ) IS NULL THEN 0 ELSE AVG( sc.s_score ) END, 2 ) AS agvScore
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
GROUP BY
st.s_id
ORDER BY
agvScore DESC
) a
SELECT
a.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_id,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_id = '01'
ORDER BY
sc.s_score DESC
LIMIT 0,
3
) a UNION ALL
SELECT
b.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_id,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_id = '02'
ORDER BY
sc.s_score DESC
LIMIT 0,
3
) b UNION ALL
SELECT
c.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_id,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_id = '03'
ORDER BY
sc.s_score DESC
LIMIT 0,
3
) c
SELECT
c.c_id,
c.c_name,
COUNT( 1 )
FROM
course c
LEFT JOIN score sc ON sc.c_id = c.c_id
INNER JOIN student st ON st.s_id = c.c_id
GROUP BY
c.c_id
SELECT
st.s_id,
st.s_name
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
GROUP BY
st.s_id
HAVING
COUNT( 1 ) = 2
SELECT s_sex, COUNT(1) FROM student GROUP BY s_sex
SELECT * FROM student WHERE s_name LIKE '%德%'
select st.s_name,st.s_sex,count(1) from student st group by st.s_name,st.s_sex having count(1)>1
SELECT st.* FROM student st WHERE st.s_birth LIKE '1990%';
SELECT
c.c_id,
c_name,
AVG( sc.s_score ) AS scoreAvg
FROM
course c
INNER JOIN score sc ON sc.c_id = c.c_id
GROUP BY
c.c_id
ORDER BY
scoreAvg DESC,
c.c_id ASC;
SELECT
st.s_id,
st.s_name,
( CASE WHEN AVG( sc.s_score ) IS NULL THEN 0 ELSE AVG( sc.s_score ) END ) scoreAvg
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
GROUP BY
st.s_id
HAVING
scoreAvg > '85';
SELECT
*
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
AND sc.s_score < 60
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_name = '数学';
SELECT
*
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
LEFT JOIN course c ON c.c_id = sc.c_id
ORDER BY
st.s_id,
c.c_name;
SELECT
st.s_id,st.s_name,c.c_name,sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
LEFT JOIN course c ON c.c_id = sc.c_id
WHERE
st.s_id IN (
SELECT
st2.s_id
FROM
student st2
LEFT JOIN score sc2 ON sc2.s_id = st2.s_id
GROUP BY
st2.s_id
HAVING
MIN( sc2.s_score )>= 70
ORDER BY
st2.s_id
)
SELECT
st.s_id,
c.c_name,
st.s_name,
sc.s_score
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
AND sc.s_score < 60
INNER JOIN course c ON c.c_id = sc.c_id
SELECT
st.s_id,
st.s_name,
sc.s_score
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
AND sc.c_id = '01'
AND sc.s_score >= 80;
SELECT
c.c_id,
c.c_name,
COUNT( 1 )
FROM
course c
INNER JOIN score sc ON sc.c_id = c.c_id
GROUP BY
c.c_id;
SELECT
st.*,
sc.s_score
FROM
student st
INNER JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
INNER JOIN teacher t ON t.t_id = c.t_id
AND t.t_name = '死亡歌颂者'
ORDER BY
sc.s_score DESC
LIMIT 0,1;
SELECT
st.s_id,
st.s_name,
sc.c_id,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
LEFT JOIN course c ON c.c_id = sc.c_id
WHERE
(
SELECT
COUNT( 1 )
FROM
student st2
LEFT JOIN score sc2 ON sc2.s_id = st2.s_id
LEFT JOIN course c2 ON c2.c_id = sc2.c_id
WHERE
sc.s_score = sc2.s_score
AND c.c_id != c2.c_id
)>1;
SELECT
a.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_id = '01'
ORDER BY
sc.s_score DESC
LIMIT 0,
2
) a UNION ALL
SELECT
b.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_id = '02'
ORDER BY
sc.s_score DESC
LIMIT 0,
2
) b UNION ALL
SELECT
c.*
FROM
(
SELECT
st.s_id,
st.s_name,
c.c_name,
sc.s_score
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
INNER JOIN course c ON c.c_id = sc.c_id
AND c.c_id = '03'
ORDER BY
sc.s_score DESC
LIMIT 0,
2
) c;
写法 2
SELECT
a.s_id,
a.c_id,
a.s_score
FROM
score a
WHERE
( SELECT COUNT( 1 ) FROM score b WHERE b.c_id = a.c_id AND b.s_score > a.s_score ) <= 2
ORDER BY
a.c_id;
要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
SELECT
c.c_id,
COUNT( 1 )
FROM
score sc
LEFT JOIN course c ON c.c_id = sc.c_id
GROUP BY
c.c_id
HAVING
COUNT( 1 ) > 5
ORDER BY
COUNT( 1 ) DESC,
c.c_id ASC;
SELECT
st.s_id
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
GROUP BY
st.s_id
HAVING
COUNT( 1 )>= 2;
SELECT
st.*
FROM
student st
LEFT JOIN score sc ON sc.s_id = st.s_id
GROUP BY
st.s_id
HAVING
COUNT( 1 )=(
SELECT
COUNT( 1 )
FROM
course)
SELECT
st.*,
TIMESTAMPDIFF(
YEAR,
st.s_birth,
NOW())
FROM
student st
SELECT
st.*
FROM
student st
WHERE
WEEK (
NOW())+ 1 = WEEK (
DATE_FORMAT( st.s_birth, '%Y%m%d' ))
SELECT
st.*
FROM
student st
WHERE
WEEK (
NOW())+ 1 = WEEK (
DATE_FORMAT( st.s_birth, '%Y%m%d' ));
SELECT
st.*
FROM
student st
WHERE
MONTH (
NOW())= MONTH (
DATE_FORMAT( st.s_birth, '%Y%m%d' ));
SELECT
st.*
FROM
student st
WHERE
MONTH (
TIMESTAMPADD(
MONTH,
1,
NOW()))= MONTH (
DATE_FORMAT( st.s_birth, '%Y%m%d' ));
点击预览在线版: 阿里巴巴开发手册
内容偏向基础适合各个阶段人员的学习与巩固,如果对您还有些帮助希望给博主点个赞支持一下,感谢!