初始化数据库
1、DB(database):数据库,保存一组有组织的数据的容器
2、2、DBMS:(Database Management System)数据库管理系统,又称为数据库软件(产品),用于管理DB中的数据
3、3、SQL:(Structure Query Language)结构化查询语言,用于和DBMS通信的语言
数据库的启动
启动关闭数据库 net start mysql ; net stop mysql
我的电脑”→“管理”→“服务”在服务器的列表中找到mysql服务并右键单击,在弹出的快捷菜单中,完成MySQL服务的各种操作(启动、重新启动、停止、暂停和恢复)
进入数据库 mysql -u root -p 退出数据库,命令行exit; mysql > quit;
DDL 数据定义语言
(Data Defintion Language)语句:数据定义语句,用于定义不同的数据对象、数据库、表、列、索引等。常用的语句关键字包括create、drop、alter等。
对数据库的操作
SHOW DATABASES;
CREATE DATABASE 2104javaee;
USE 数据库名;
SHOW TABLES;
show tables from 库名;
DROP DATABASE IF EXISTS 数据库名;
对表的操作
CREATE TABLE 表名student(
id int(32) PRIMARY KEY auto_increment [COMMENT ‘注释’],
name VARCHAR(32) NOT NULL ,
sex VARCHAR(32),
age int(3) DEFAULT 4 ,
salary FLOAT(8,2) DEFAULT 4 ,
course VARCHAR(32)
)ENGINE=InnoDB [COMMENT ‘用户表’] DEFAULT CHARSET=utf8
SHOW CREATE TABLE db_student;
显示的结果
CREATE TABLE `db_student` (
`s_id` int(3) DEFAULT NULL,
`s_name` varchar(32) DEFAULT NULL,
`s_sex` char(3) DEFAULT NULL,
`s_salary` float(8,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
DESC 表名;
ALTER TABLE 旧表名 RENAME TO 新表名 ;
ALTER TABLE db_student rename student;
ALTER TABLE 表名 COMMENT '新注释'
DROP TABLE 表名;
TRUNCATE TABLE 表名; 清空数据
deleate table 表名;
三者的区别:
drop:删除表所有数据与表的数据结构,也就是表直接不存在了(无法回滚)
truncate: 清空表中所有的数据,速度快,不可回滚;实质是删除整张表包括数据再重新创建表(一旦提交不可回滚)
delete: 逐行删除数据,每步删除都是有日志记录的,可以回滚数据;实质是逐行删除表中的数据
总结:
速度:一般来说: drop> truncate > delete
安全性:小心使用 drop 和 truncate,尤其没有备份的时候.否则哭都来不及
使用上,想删除部分数据行用 delete,注意带上where子句. 回滚段要足够大.
想删除表,当然用 drop;想保留表而将所有数据删除,如果和事务无关,用truncate即可。如果和事务有关,用delete
ALTER TABLE 表名 ADD COLUMN 字段名 字段类型(长度) [是否可为空,或者设置默认值] [COMMENT '注释'] [AFTER 指定某字段] ;
ALTER TABLE student ADD COLUMN `sex` VARCHAR(5) NOT NULL DEFAULT 'ssss' COMMENT '性别' AFTER age;
alter table white_user_new add column erp varchar(32) not null comment 'erp账号' after name ;
ALTER TABLE 表名 ADD 字段名 VARCHAR(32);
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度) 新默认值 新注释;
alter table table1 modify column1 decimal(10,2) [DEFAULT NULL] [COMMENT '注释'];
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 新数据类型(长度) [DEFAULT] [COMMENT '注释']];
alter table table1 change column1 column1 varchar(100) DEFAULT 1.2 COMMENT '注释';
ALTER TABLE 表名 DROP 字段名;
ALTER TABLE student DROP column1;
放到第一位 ALTER TABLE student MODIFY age INT(3) FIRST
ALTER TABLE student MODIFY 字段1 字段1的属性 AFTER 字段2
复制表使用子查询创建表
1. CREATE TABLE 新表 SELECT * FROM 旧表 WHERE 1=2;
2.CREATE TABLE sing3 LIKE sing;
注意上面两种方式,前一种方式是不会复制时的主键类型和自增方式是不会复制过去的,而后一种方式是把旧表的所有字段类型都复制到新表。
CREATE TABLE 新表 SELECT * FROM 旧表;
INSERT INTO 新表 SELECT * FROM 旧表
INSERT INTO 新表(字段1,字段2,…) SELECT 字段1,字段2,… FROM 旧表
CREATE TABLE table [(column, column...)] AS subquery;
create table emp1 as select * from employees;
create table emp2 as select * from employees where 1=2;
CREATE TABLE dept80
AS
SELECT employee_id, last_name,
salary*12 ANNSAL,
hire_date
FROM employees
WHERE department_id = 80;
Table
查看表的详细信息
1.查看所有表的注释
SELECT
table_name 表名,
table_comment 表的注释
FROM
information_schema.TABLES
WHERE
table_schema = '数据库名'
ORDER BY
table_name
2.查询所有表及字段的注释
SELECT
a.table_name 表名,
a.table_comment 表说明,
a.create_time 创建时间
b.COLUMN_NAME 字段名,
b.column_comment 字段说明,
b.column_type 字段类型,
b.column_key 约束
FROM
information_schema. TABLES a
LEFT JOIN information_schema. COLUMNS b ON a.table_name = b.TABLE_NAME
WHERE
a.table_schema = '数据库名'
ORDER BY
a.table_name
3.查询某表的所有字段的注释
select
COLUMN_NAME 字段名,
column_comment 字段说明,
column_type 字段类型,
column_key 约束
from information_schema.columns
where table_schema = '数据库名'
and table_name = '表名' ;
show full columns from 表名;
获取表索引
所有表索引
SELECT CONCAT('ALTER TABLE ',i.TABLE_NAME,' DROP INDEX ',i.INDEX_NAME,' ;')
FROM INFORMATION_SCHEMA.STATISTICS i
WHERE TABLE_SCHEMA = '库名' AND i.INDEX_NAME <> 'PRIMARY';
单表索引
SELECT CONCAT('ALTER TABLE ',i.TABLE_NAME,' DROP INDEX ',i.INDEX_NAME,' ;')
FROM INFORMATION_SCHEMA.STATISTICS i
WHERE TABLE_SCHEMA = 'xhkj_ques_0919' AND TABLE_NAME='t_question_bak' AND i.INDEX_NAME <> 'PRIMARY';
DML数据操作语言
( Data Manipulation Language)语句:数据操纵语句,用于添加、删除、更新数据库记录,并检查数据的完整性。常用的语句关键字主要包括insert、delete、update和等。
注意:varchar 和date型的数据要用单引号引起来
1.插入数据
字符和日期型数据应包含在单引号中。
INSERT INTO table [(column1 [, column2...])]
VALUES (value1 [, value2...]);
INSERT INTO student VALUES(1,'宋钢','男',28,8000,'JAVA');
隐式方式
INSERT INTO departments (department_id, department_name )
VALUES (30, 'Purchasing');
显式方式
INSERT INTO departments VALUES (100, 'Finance', NULL, NULL);
NOW()函数:记录当前系统的日期和时间 now()。
INSERT INTO employees (
first_name, last_name,
email, phone_number,
hiredate, job_id, salary,
commission_pct, manager_id,
department_id)
VALUES (
'Louis', 'Popp',
'LPOPP', '515.124.4567',
NOW(), 'AC_ACCOUNT', 6900,
NULL, 205, 100);
INSERT INTO world (country, population)
VALUES
('加拿大', 100),
('英国', 200),
('法国', 300),
('日本', 250),
('德国', 200),
('墨西哥', 50),
('印度', 250);
? 不必书写 VALUES 子句。
? 子查询中的值列表应与 INSERT 子句中的列名对
应
例一
INSERT INTO emp2
SELECT *
FROM employees
WHERE department_id = 90;
例一:
INSERT INTO sales_reps(id, name, salary, commission_pct)
SELECT employee_id, last_name, salary, commission_pct
FROM employees
WHERE job_id LIKE '%REP%';
更新数据
UPDATE table
SET column = value [, column = value, ...]
[WHERE condition];
UPDATE student SET 字段1 = 61,字段2=值 where 条件;
UPDATE student SET age = 61 WHERE id = 3;
UPDATE student SET salary = 8000 WHERE id>5 AND age>30;
UPDATE student SET salary = 8000 WHERE id>5 OR age>30;
删除 数据
DELETE FROM student;
TRUNCATE TABLE student;
DELETE FROM student WHERE id=2;
DQL:查询语言
注意事项:
SQL 语言大小写不敏感。SQL 可以写在一行或者多行。 关键字不能被缩写也不能分行。各子句一般要分行写。 使用缩进提高语句的可读性。
列的别名:
别名紧跟列名,也可以在列名和别名之间加入关键字 ‘AS’,别名使用双引号,以便在别名中包含空格或特殊的字符并区分大小写。 查询结果会显示成别名
SELECT last_name NAME ,phone_number phone FROM employees;
SELECT last_name AS "name",phone_number AS "phone number" FROM employees;
Where和Having
- where和having的区别
where是一个约束声明,使用where来约束来自数据库的数据; where是在结果返回之前起作用的; where中不能使用组函数。 having是一个过滤声明; 在查询返回结果集以后,对查询结果进行的过滤操作; 在having中可以使用组函数。 - .聚合函数和group by
聚合函数就是例如SUM, COUNT, MAX, 等对一组(多条)数据操作的函数,需要配合group by 来使用。 #如: SELECT SUM(population),region FROM T01_Beijing GROUP BY region; //计算北京每个分区的人数 - 3.where和having的执行顺序
where 早于 group by 早于 having where子句在聚合前先筛选记录,也就是说作用在group by 子句和having子句前,而 having子句在聚合后对组记录进行筛选
comparison_expr 关系式
expr 表达式
- 字符串可以是 SELECT 列表中的一个字符,数字,日期
1.基础查询
SELECT * FROM student;
SELECT name,age FROM student;
SELECT name AS '姓名',age AS '年龄' FROM student;
2.条件查询
- where 不能使用组函数,
- 明确:WHERE一定放在FROM后面
SELECT *|{[DISTINCT] column|expression [alias],...}
FROM table
[WHERE condition(s)];
查询数据 + 比较运算
条件表达式:> < >= <= = != <>(不等于)
SELECT name FROM student WHERE age < 28;
select * from student Where name is not null;
逻辑表达式
and(&&);or(||);not(!)
查询数据 + 去重
根据某个字段去重
SELECT DISTINCT 字段名 FROM student;
SELECT DISTINCT course FROM student;
distinct a,b,c,d abcd全部相同才是重复的
LIke模糊查询
% 表示不确定多少个字符; _ 表示一个字符
SELECT * FROM student WHERE name LIKE '%华%';
SELECT * FROM student WHERE name LIKE '_华_';
SELECT * FROM student WHERE name LIKE '华%';
查询 BETWEEN …AND…
在两个值之间:查询id在25到200之间的学生 包括边界
SELECT * FROM student WHERE id BETWEEN 25 AND200;
查询空值
SELECT * FROM student WHERE name is NULL;
IN(set)
条件同时包含多个值
会把manger_id等于100,,101,201 的查询出来
SELECT employee_id, last_name, salary, manager_id FROM employees WHERE manager_id IN (100, 101, 201);
NOT IN
不不包含表中的任意一个
ANY/SOME
会从括号中返回某一个项出来比较,如果<ANY(xx,xx) 会查询出满足小于最大的那个 ,相当于 <(MAX(xx,xx))
SELECT last_name, job_id FROM employees
WHERE job_id <> ANY('IT_PROG', 'ST_CLERK', 'SA_REP');
ALL
会从括号中返回所有项出来比较
SELECT last_name, job_id FROM employees
WHERE job_id <> ALL('IT_PROG', 'ST_CLERK', 'SA_REP');
条件包含逻辑运算 and or not
SELECT employee_id FROM employees WHERE salary >= 10000 OR job_id <200
SELECT last_name, job_id FROM employees WHERE job_id NOT IN ('IT_PROG', 'ST_CLERK', 'SA_REP');
3.排序查询
ORDER BY 子句在SELECT语句的结尾。
需求:按照年龄排升序
SELECT * FROM student ORDER BY age ASC;
需求:按照工资排降序
SELECT * FROM student ORDER BY salary DESC;
需求:年龄做升序,年龄相同工资做降序
SELECT * FROM student ORDER BY age ASC,salary DESC;
SELECT employee_id, last_name, salary*12 annsal
FROM employees
ORDER BY annsal;
限制查找的数量
SELECT * FROM student LIMIT 3;
还可以这样
SELECT * FROM student ORDER BY age ASC,salary DESC SELECT * FROM student LIMIT 3
分页
限制查找的数据条数量
查询所有是学生表中的数据,每次只查询num条
SELECT * FROM student LIMIT 偏移量,获取条数;
SELECT * FROM student LIMIT 1,3;
\# 分页的公式:SELECT * FROM student LIMIT (页数-1)*num,num);
\# 需求:分页查询,每一页展示3个信息
SELECT * FROM student LIMIT 0,3;
SELECT * FROM student LIMIT 3,3;
SELECT * FROM student LIMIT 6,3;
\# 需求:取这个班年龄最大的前三个人(思路:先排序再限制)
SELECT * FROM student ORDER BY age DESC LIMIT 3;
4. 组函数
分组函数作用于一组数据,并对一组数据返回一个值
SELECT [column,] group_function(column), … FROM table [WHERE condition] [GROUP BY column] [ORDER BY column];
- 可以对数值型数据使用AVG 和 SUM 函数
- 可以对任意数据类型的数据使用 MIN 和 MAX 函数
- COUNT(*) 返回表中记录总数,适用于任意数据类型
求和
SELECT SUM(salary) FROM student;
平均值
SELECT AVG(age) FROM student;
最大值
SELECT MAX(age) FROM student;
最小值
SELECT min(age) FROM student;
个数count
(返回expr不会空的记录总数,所以字段一般选择主键即可)
SELECT COUNT(id) FROM student;
分组数据GROUP BY
可以使用GROUP BY子句将表中的数据分成若干组
分组前筛选 where 原始表 group by的前面 分组后筛选 having 分组后的结果 group by 的后面
SELECT column, group_function(column)
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY column];
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id ;
SELECT AVG(salary)
FROM employees
GROUP BY department_id ;
SELECT department_id ,job_id,SUM(salary) FROM employees GROUP BY department_id;
以第一列分组 ,有时候查询出 结果,第一列有多个值就需要使用到
过滤分组Having
- 使用了组函数。
- 满足HAVING 子句中条件的分组将被显示
SELECT column, group_function
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column];
SELECT
department_id,
MAX (salary)
FROM
employees
GROUP BY department_id
HAVING MAX (salary) > 1000;
5.时间日期函数
时间数据类型
1.DATETIME:
类型用在你需要同时包含日期和时间信息的值时。MySQL检索并且以’YYYY-MM-DD HH:MM:SS’格式显示DATETIME值,支持的范围是’1000-01-01 00:00:00’到’9999-12-31 23:59:59’。(“支持”意味着尽管更早的值可能工作,但不能保证他们可以。)
2.DATE:
类型用在你仅需要日期值时,没有时间部分。MySQL检索并且以’YYYY-MM-DD’格式显示DATE值,支持的范围是’1000-01-01’到’9999-12-31’。
3.TIMESTAMP:
每张表的第一个timestamp会随着插入与修改自动更新
可以表示年月日时分秒,你可以使用它自动地用当前的日期和时间标记INSERT或UPDATE的操作。
CREATE TABLE test(
i INT,
a TIMESTAMP,
b TIMESTAMP
)
INSERT INTO test(i) VALUES(1)
SELECT * FROM test
4.TIME:
数据类型表示一天中的时间。MySQL检索并且以"HH:MM:SS"格式显示TIME值。支持的范围是’00:00:00’到’23:59:59’。
时间函数
SELECT NOW();
SELECT SYSDATE();
给入班时间加一天
SELECT s_num,DATE_ADD(s_beginDate,INTERVAL 1 DAY) '加一天的日期' FROM sing;
select date_add(now(), interval 1 day);
select date_add(now(), interval 1 hour);
select date_add(now(), interval 1 minute);
select date_add(now(), interval 1 second);
3.timestampdiff函数 获取两个时间之间的时间里的差 时间正向流失 所以 有正负,后面减前面
SELECT TIMESTAMPDIFF(DAY,'2001-05-05','2001-5-01') 天数差;
SELECT TIMESTAMPDIFF(HOUR,'2001-05-05','2001-5-01') '小时差';
SELECT TIMESTAMP('2008-08-08 08:00:00','01:00:00') '增加后的时间' ;
NULL值处理
首先在mysql中,NULL表示的是“a missing unknown value”,而字符串’'是一个确定的值,这本质上就已经不一样了,NULL是指没有值,而空字符串 ” 则表示值是存在的,只不过是个空值
SELECT * FROM sing WHERE s_beginDate IS NULL;
用order by … asc时,null值会被放在最前面,而用order by … desc时,null时会被放在最后面,相当于null是一个无穷小的值。
Ifnull(a,b) 表示如果a为null 就赋值为b
SELECT AVG(s_level) FROM sing;
SELECT AVG(IFNULL (s_level,0)) FROM sing;
多表查询join
使用连接在多个表中查询数据,把多个表中 有相同的数据把他对应起来
SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column1 = table2.column2;
SELECT
beauty.`id`,
NAME,
boyname
FROM
beauty,
boys
WHERE beauty.id = boys.id;
SELECT
bt.id,
NAME,
boyName
FROM
`beauty` bt,
boys b
WHERE bt.`id` = b.`id`;
JOIN 使用on字句
当多个表中有关联数据 如 A.key=B.key 时 将两个表关联起来 可以使用join on
分类
- 内连接 [inner] join on 只显示匹配项
- 外连接 分左连接和右连接 (from后面的是左边,join后面的是右边)
- 左外连接 left [outer] join on 显示 左边的所有项,只显示右边匹配项
- 左外连接 right [outer] join on 显示 右边的所有项,只显示左边匹配项
SELECT bt.id,NAME,boyname
FROM beauty bt
Inner join boys b
On bt.`boyfriend_id`=b.id ;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MUovw0ib-1636902205458)(D:\develops\note\我的坚果云\二阶段\图库\sql连接2.png)]
常用函数
1.字符控制函数
大小写控制函数 | |
---|
LOWER(‘SQL Course’) to小写 | sql course | UPPER(‘SQL Course’) to大写 | SQL COURSE | CONCAT(‘Hello’, ‘World’) 拼接 | HelloWorld | SUBSTR(‘HelloWorld’,1,5) 截取子串 | Hello | LENGTH(‘HelloWorld’) 获取字符个数 | 10 | INSTR(‘HelloWorld’, ‘W’) 返回子串第一次出现的索引 | 6 | LPAD(salary,10,’*’) 左填充 | *********24000 | RPAD(salary, 10, ‘*’) 右填充 | 24000******* | TRIM(‘H’ FROM ‘HelloWorld’) 去前后指定的空格和字符 | elloWorld | REPLACE(‘abcd’,‘b’,‘m’) 替换 | amcd | | |
2、数学函数 round 四舍五入 ROUND(45.926, 2) — 45.93 rand 随机数 floor向下取整 ceil向上取整 mod取余 MOD(1600, 300) ----100 truncate截断 TRUNC(45.926, 2) ----45.92
3、日期函数
-
now-----当前系统日期+时间 -
curdate当前系统日期 -
curtime当前系统时间 -
year:返回年 -
month:返回月 -
day:返回日 -
还有返回时分秒 hour;minute;second -
str_to_date 将日期格式的字符转换成指定格式的日期
- STR_TO_DATE(‘9-13-1999’,’%m-%d-%Y’) -----1999-09-13
-
date_format将日期转换成字符
- DATE_FORMAT(‘2018/6/6’,‘%Y年%m月%d日’) -------2018年06月06日
%Y 四位的年份 ; %y 2位的年份 ; %m 月份(01,02…11,12 ); %c 月份(1,2,…11,12 ) %d 日(01,02,…); %H 小时(24小时制) ; %h 小时(12小时制) %i 分钟(00,01…59) ; %s 秒(00,01,…59)
流程控制函数 if then else…
CASE 表达式
CASE expr WHEN comparison_expr1 THEN return_expr1
[WHEN comparison_expr2 THEN return_expr2
WHEN comparison_exprn THEN return_exprn
ELSE else_expr]
END
case :指定字段
when:当什么条件 或者常量值
then:满足上面的条件 就干什么,可以对字段内容进行更改,进行加减乘除
else:前面的条件都不满足
end:结束语
SELECT
last_name,job_id, salary,
CASE
job_id (字段或变量或表达式)
WHEN 'IT_PROG' THEN 1.10 * salary
WHEN 'ST_CLERK' THEN 1.15 * salary
WHEN 'SA_REP' THEN 1.20 * salary
ELSE salary
END "REVISED_SALARY"
FROM employees;
SELECT
last_name,job_id,salary,
CASE
job_id
WHEN job_id='IT_PROG' THEN 1.10 * salary
WHEN job_id='ST_CLERK' THEN 1.15 * salary
WHEN job_id='SA_REP' THEN 1.20 * salary
ELSE salary
END "REVISED_SALARY"
FROM employees;
SELECT
SUM(CASE s_level WHEN 1 THEN 1 ELSE 0 END) '初级',
SUM(CASE s_level WHEN 2 THEN 1 ELSE 0 END) '中级',
SUM(CASE s_level WHEN 3 THEN 1 ELSE 0 END) '高级'
FROM sing;
5、其他函数
版本 SELECT @@version; 当前库 SELECT DATABASE(); 当前连接用户 SHOW PROCESSLIST;
?
5.子查询:
出现在其他语句中的select语句,称为子查询或内查询
- 子查询 (内查询) 在主查询之前一次执行完成。
- 子查询的结果被主查询(外查询)使用 。
- 外部的查询语句,称为主查询或外查询
SELECT select_list
FROM table
WHERE expr operator
(SELECT select_list
FROM table);
分类: 按子查询出现的位置:
- select后面:仅仅支持标量子查询
- from后面:支持表子查询
- where或having后面:★
- 标量子查询(单行) √
- 列子查询 (多行) √
- 行子查询
- exists后面(相关子查询)
表子查询
按结果集的行列数不同: 标量子查询(结果集一行一列) 列子查询(结果集一列多行) 行子查询(结果集一行多列) 表子查询(结果集一般为多行多列)
一、where或having后面
1.标量子(结果集只有一行一列)
1.查询Abel的工资
SELECT salary
FROM employees
WHERE last_name = 'Abel';
2.查询员工的信息,满足 salary>1结果
SELECT last_name
FROM employees
WHERE salary >
(SELECT salary
FROM employees
WHERE last_name = 'Abel');
1.查询141号员工的job_id
SELECT job_id
FROM employees
WHERE employee_id = 141;
2.查询143号员工的salary
SELECT salary
FROM employees
WHERE employee_id = 143
3.查询员工的姓名,job_id 和工资,要求job_id=1并且salary>2
SELECT last_name,job_id,salary
FROM employees
WHERE job_id = (
SELECT job_id
FROM employees
WHERE employee_id = 141
) AND salary>(
SELECT salary
FROM employees
WHERE employee_id = 143
);
1.查询50号部门的最低工资
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
2.查询每个部门的最低工资
SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
3.在2基础上筛选,满足min(salary)>1
SELECT MIN(salary),department_id
FROM employees
GROUP BY department_id
HAVING MIN(salary)>(
SELECT MIN(salary)
FROM employees
WHERE department_id = 50
);
2.列子查询,结果集一列多行
体会ALL 和ANY
1查询location_id是1400或1700的部门编号
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
2.查询员工姓名,要求部门号是1列表中的某一个 (每一个department_id 都会拿出来比较)
SELECT last_name
FROM employees
WHERE department_id <>ALL(
SELECT DISTINCT department_id
FROM departments
WHERE location_id IN(1400,1700)
);
1.查询job_id为‘IT_PROG’部门任一工资
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
2查询员工号、姓名、job_id 以及salary,salary<(1)的任意一个
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<ANY(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<(
SELECT MAX(salary)
FROM employees
WHERE job_id = 'IT_PROG'
)
AND job_id<>'IT_PROG';
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<ALL(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<(
SELECT MIN( salary)
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
3.行子(一行多列)
1.查询最小的员工编号
SELECT MIN(employee_id)
FROM employees
2.查询最高工资
SELECT MAX(salary)
FROM employees
3.查询员工信息
SELECT *
FROM employees
WHERE employee_id=(
SELECT MIN(employee_id)
FROM employees
)AND salary=(
SELECT MAX(salary)
FROM employees
);
SELECT *
FROM employees
WHERE (employee_id,salary)=(
SELECT MIN(employee_id),MAX(salary)
FROM employees
);
二、selsect后面
仅仅支持标量子查询
SELECT d.*,(
SELECT COUNT(*)
FROM employees e
WHERE e.department_id = d.`department_id`
) 个数 (给后面的查询结果起了个别名,不然第一行会显示成SELECT COUNT(*) FROM employees e,比较长
WHERE e.department_id = d.`department_id`)
FROM departments d;
案例2:查询员工号=102的部门名
SELECT department_name,e.department_id
FROM departments d
INNER JOIN employees e
ON d.department_id=e.department_id
WHERE e.employee_id=102
三、from后面
将子查询结果充当一张表,要求必须起别名
1.查询每个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
2. SELECT * FROM job_grades;
3.连接1的结果集(别名为ag_dep)和job_grades表,筛选条件平均工资 between lowest_sal and highest_sal
SELECT ag_dep.*,g.`grade_level`
FROM (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;
四、exists后面(相关子查询)
SELECT EXISTS(SELECT employee_id FROM employees WHERE salary=300000); 返回结果为0
SELECT department_name
FROM departments d
WHERE d.`department_id` IN(
SELECT department_id
FROM employees
)
SELECT department_name
FROM departments d
WHERE EXISTS(
SELECT *
FROM employees e
WHERE d.`department_id`=e.`department_id`
);
SELECT bo.*
FROM boys bo
WHERE bo.id NOT IN(
SELECT boyfriend_id
FROM beauty
)
SELECT bo.*
FROM boys bo
WHERE NOT EXISTS(
SELECT boyfriend_id
FROM beauty b
WHERE bo.`id`=b.`boyfriend_id`
);
解决编码问题
Set charset gbk 临时改变命令行运行程序编码方式
数据类型
在MySQL里面我们将数据类型分为了以下一些类型:
-
数值类型(整型、浮点) -
字符串类型 -
日期时间类型 -
复合类型
整型
MySQL数据类型 | 所占字节 | 值范围 |
---|
tinyint | 1字节 | -128127,无符号:0255 | smallint | 2字节 | 有符号:-3276832767<br/>无符号:065535 | mediumint | 3字节 | -83886088388607<br/>无符号:01677215 | int | 4字节 | 范围-21474836482147483647<br/>无符号:04294967295 | bigint | 8字节 | ±9.22*10的18次方 |
UNSIGNED(无符号) 主要用于整型和浮点类型,使用无符号。即,没有前面面的-(负号)。 存储位数更长。tinyint整型的取值区间为,-128~127。而使用无符号后可存储0-255个长度。
创建时在整型或浮点字段语句后接上:
Unsigned
浮点类型
MySQL数据类型 | 所占字节 | 值范围 |
---|
float(m, d) | 4字节 | 单精度浮点型,m总个数,d小数位 | double(m, d) | 8字节 | 双精度浮点型,m总个数,d小数位 | decimal(m, d) | | decimal是存储为字符串的浮点数 | Bit | 1-8 | Bit(1)~bit(8) |
字符类型
MySQL数据类型 | 所占字节 | 值范围 |
---|
CHAR | 0-255字节 | 定长字符串 | VARCHAR | 0~65535字节 | 变长字符串 | TINYBLOB | 0-255字节 | 不超过255个字符的二进制字符串 | TINYTEXT | 0-255字节 | 短文本字符串 | BLOB | 0-65535字节 | 二进制形式的长文本数据 | TEXT | 0-65535字节 | 长文本数据 | MEDIUMBLOB | 0-16 777 215字节 | 二进制形式的中等长度文本数据 | MEDIUMTEXT | 0-16 777 215字节 | 中等长度文本数据 | LOGNGBLOB | 0-4 294 967 295字节 | 二进制形式的极大文本数据 | LONGTEXT | 0-4 294 967 295字节 | 极大文本数据 | VARBINARY(M) | 允许长度为0~65535个字节的定长字节符串 | 值的长度+1个字节 | BINARY(M) | 0~255 | 允许长度0-M个字节的定长字节符串 |
时间类型
MySQL数据类型 | 所占字节 | 值范围 |
---|
date | 4字节 | 日期,格式:2014-09-18 | time | 3字节 | 时间,格式:08:42:30 | datetime | 8字节 | 日期时间,格式:2014-09-18 08:42:30 | timestamp | 4字节 | 自动存储记录修改的时间 | year | 1字节 | 年份 |
注意
-
时间类型在web系统中用的比较少,很多时候很多人喜欢使用int来存储时间。插入时插入的是unix时间戳,因为这种方式更方便计算。在前端业务中用date类型的函数,再将unix时间戳转成人们可识别的时间。 -
上面的类型你可以根据实际情况实际进行选择,有些人为了在数据库管理中方便查看,也有人使用datetime类型来存储时间。
约束
约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、唯一性。
1.主键约束 primary key
主键约束相当于 唯一约束 + 非空约束 的组合,主键约束列不允许重复,也不允许出现空值。
每个表最多只允许一个主键,建立主键约束可以在列级别创建,也可以在表级别创建。
当创建主键的约束时,系统默认会在所在的列和列组合上建立对应的唯一索引。
create table temp(
id int(3) primary key,
name varchar(20)
);
create table temp(
id int ,
name varchar(20),
pwd varchar(20),
primary key(id, name)
);
alter table temp drop primary key;
alter table temp add primary key(id,name);
alter table temp modify id int primary key;
2、外键约束 foreign key
1.外键约束是保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系。
- 从表的外键值必须在主表中能找到或者为空。当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据,然后才可以删除主表的数据。
- 还有一种就是级联删除子表数据。
- 注意:外键约束的参照列,在主表中引用的只能是主键或唯一键约束的列注意:字段和参照1、检查sc表的外键字段的类型以及大小是否和s表c表完全一致
2、试图引用的其中一个外键没有建立起索引,或者不是一个primary key , 如果其中一个不是primary key 的话,你必须为它创建一个索引。
3、一个或两个表是MyISAM引擎的表,若想要使用外键约束,必须是InnoDB引擎
create table temp(
id int primary key,
name varchar(20)
);
create table temp2(
id int,
name varchar(20),
classes_id int,
foreign key(id) references temp(id)
);
create table classes(
id int,
name varchar(20),
number int,
primary key(name,number)
);
create table student(
id int auto_increment primary key,
name varchar(20),
classes_name varchar(20),
classes_number int,
foreign key(classes_name, classes_number) references classes(name, number) );
在创建表时创建 所以key后不跟表名
注意:
alter table student drop foreign key 外键名;
alter table表一 add foreign key(classes_name, classes_number) references 表二(name, number);
3、 唯一约束unique
唯一约束是指定table的列或列组合不能重复,保证数据的唯一性。
唯一约束不允许出现重复的值,但是可以为多个null。
同一个表可以有多个唯一约束,多个列组合的约束。
在创建唯一约束时,如果不给唯一约束名称,就默认和列名相同。
唯一约束不仅可以在一个表内创建,而且可以同时多表创建组合唯一约束。
create table temp(
id int not null ,
name varchar(20),
password varchar(10),
unique(name,password)
);
alter table temp add unique (name, password);
alter table temp modify name varchar(25) unique;
alter table temp drop index name;
4、非空约束 not null 与 默认值 default
非空约束用于确保当前列的值不为空值,非空约束只能出现在表对象的列上。
Null类型特征:
所有的类型的值都可以是null,包括int、float 等数据类型
create table temp(
id int not null,
name varchar(255) not null default 'abc',
sex char null
);
alter table temp modify sex varchar(2) not null;
alter table temp modify sex varchar(2) null;
alter table temp modify sex varchar(2) default 'abc' null;
视图
含义:虚拟表,抽取真实表的部分字段到虚拟表中,和普通表一样使用,mysql5.1版本出现的新特性,是通过表动态生成的数据,一般会定义子账户权限,只读 。只保存了sql逻辑,不保存查询结果
视图的好吃
- 重用sql语句
- 简化复杂的sql操作,不必知道它的查询细节
- 保护数据,提高安全性
创建视图:
create [or replace] view 视图名 AS select 字段名 1,字段名2,from 表名 [where 条件] [with check option]
? with check option – 当修改值超过条件时,不允许修改
? or replace – 如果已有视图,则替换
EXP:create or replace view view1 as select name,age from student [where age>20 with check option];
查询视图数据:select * from 视图名
插入视图数据insert into 视图名(字段1,字段2)values(字段1的值,字段2的值);
修改视图数据:update 视图名 set 字段=”值”;
删除视图:drop view 视图名
存储过程
[ delimiter XX ]
create procedure myprocedure01()
begin
select * from student;
select * from class;
endxx
[ delimiter ; ]
call myprocedure01();
参数列表
输入类型的参数
输出类型的参数
输入输出类型的参数
[ delimiter XX ]
create procedure myprocedure02(in s_id int(100))
begin
select * from student where id = s_id;
end
[ delimiter ; ]
call myprocedure02();
[ delimiter XX ]
create procedure myprocedure03(in s_id int(100), out rusername varchar(100) )
begin
select username into rusername from student where id = s_id;
end
[ delimiter ; ]
call myprocedure03(1,@a);
select @a;
[ delimiter XX ]
create procedure myprocedure04(in param int(100) )
begin
select age into param from student where id= param ;
end
[ delimiter ; ]
set @a = 1;
call myprocedure04(@a);
select @a;
[ delimiter XX ]
create procedure myprocedure05(out s_out int(100) )
begin
declare a int default 0;
select count(1) into a from student;
set s_out = a;
end
[ delimiter ; ]
call myprocedure05(@a);
select @a;
如果存在就删除存储过程:drop procedure if exists procedure_name;
函数
绝对值函数:select abs(字段) from 表 ps:此函数指的是求绝对值
平方根函数:select sqrt(9) ps:得到的值为3
求余函数:select mod(10,3) / select 10%3 ps:得到的值为1
随机函数:select rand() ps:得到的值为0~1
幂运算函数:select pow(10,2) ps:10的2次方
长度函数:select length(‘内容’)
合并函数:select concat(’hello’,’world’)
截取字符串函数:select substring(字段,start,end)
当前日期函数:curdate()
当前时间函数:curtime()
当前日期+时间函数:now()
年函数:year(now())
月函数:month(now())
日函数:dayofmonth(now())
时函数:hour(now())
分函数:minute(now())
秒函数:second(now())
时间格式函数:date_format(now(),’%Y年%m月%d日 %H时%i分%s秒’) as ‘别名’
语法:
create function 函数名([参数列表]) returns 数据类型
begin
sql语句;
return 值;
end
create function method01() returns int return 666;
SELECT method01();
delimiter xx
create function method02() returns int
begin
declare c int;
select age into c from student where id=1 ;
return c;
end xx
delimiter ;
select method02();
delimiter xx
create function method03(s_name VARCHAR(32)) returns int
begin
declare c int;
select age into c from student where name=s_name ;
return c;
end xx
delimiter ;
select method03('bbb');
drop function method03;
fault 默认值]; declare a int default 0; //给变量赋值 //set a = 1000; select count(1) into a from student; set s_out = a; end [ delimiter ; ]
call myprocedure05(@a); — 调用存储过程 select @a;
如果存在就删除存储过程:drop procedure if exists procedure_name;
# 函数
```sql
#数学函数:
绝对值函数:select abs(字段) from 表 ps:此函数指的是求绝对值
平方根函数:select sqrt(9) ps:得到的值为3
求余函数:select mod(10,3) / select 10%3 ps:得到的值为1
随机函数:select rand() ps:得到的值为0~1
幂运算函数:select pow(10,2) ps:10的2次方
#字符串函数:
长度函数:select length(‘内容’)
合并函数:select concat(’hello’,’world’)
截取字符串函数:select substring(字段,start,end)
#日期/时间函数:
当前日期函数:curdate()
当前时间函数:curtime()
当前日期+时间函数:now()
年函数:year(now())
月函数:month(now())
日函数:dayofmonth(now())
时函数:hour(now())
分函数:minute(now())
秒函数:second(now())
时间格式函数:date_format(now(),’%Y年%m月%d日 %H时%i分%s秒’) as ‘别名’
#自定义函数
语法:
create function 函数名([参数列表]) returns 数据类型
begin
sql语句;
return 值;
end
# 最简单的仅有一条sql的函数
create function method01() returns int return 666;
SELECT method01();
# 带返回值的函数
delimiter xx
create function method02() returns int
begin
declare c int;
select age into c from student where id=1 ;
return c;
end xx
delimiter ;
select method02();
# 带返回值和参数的函数
delimiter xx
create function method03(s_name VARCHAR(32)) returns int
begin
declare c int;
select age into c from student where name=s_name ;
return c;
end xx
delimiter ;
select method03('bbb');
# 删除函数:
drop function method03;
|