MySQL基础

-- mysql               #本地登录,默认用户root,空密码,用户为root@127.0.0.1
-- mysql -uroot -p1234 #本地登录,指定用户名和密码,用户为root@127.0.0.1
-- mysql -uroot -p1234 -h 192.168.31.95 #远程登录,用户为root@192.168.31.95
-- 数据库操作(DDL:Data Definition Languages)
--创建数据库(在磁盘上创建一个对应的文件夹)
CREATE DATABASE [IF NOT EXISTS ] aggressive2020 [character SET utf8]
--查看数据库
SHOW databases; --查看所有数据库
show CREATE DATABASE aggressive2019 --查看数据库的创建方式
ALTER DATABASE aggressive2019 CHARACTER SET utf8 --修改数据库
use aggressive2019;--使用数据库
SELECT database();--查看当前使用的数据库

--数据表操作
CREATE TABLE employee(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),gender bit DEFAULT 1,
birthday DATE,
entry_data date,
job VARCHAR(20),
salary DOUBLE(4,2) UNSIGNED,
resume text);
--查看表结构
DESC employee;
--查看表结构
SHOW columns from employee;
--查看当前数据库表建表语句
SHOW CREATE TABLE employee;
--增加列(字段)ALTER
ALTER TABLE employee ADD addr VARCHAR(20) NOT NULL UNIQUE AFTER name;
--添加多个字段
ALTER TABLE employee ADD age int FIRST , ADD workage VARCHAR(20) AFTER addr;
--修改一列类型 modify
ALTER TABLE employee MODIFY age TINYINT DEFAULT 20;
--修改列名 change
ALTER TABLE employee CHANGE age AGE INT DEFAULT 28 FIRST;
--删除一列
ALTER TABLE employee DROP addr;
--修改表名
RENAME TABLE employee to employee1;
--修改表所用的字符集
ALTER TABLE employee CHARACTER SET utf8;
--删除表
drop table employee;
--添加主键,删除主键
ALTER TABLE employee add PRIMARY KEY(id);
ALTER TABLE employee MODIFY id INT AUTO_INCREMENT;
--删除主键
alter table employee modify id int;
ALTER TABLE employee drop PRIMARY KEY ;
--添加唯一索引
ALTER TABLE employee ADD UNIQUE INDEX index_age(age);
--添加联合索引
ALTER TABLE employee ADD UNIQUE INDEX name_age(name,age);
--删除唯一索引
ALTER TABLE employee DROP INDEX name_age;

--创建文章表
CREATE TABLE article(
  id INT PRIMARY KEY AUTO_INCREMENT,
  title VARCHAR(20),
  publish_date INT,
  click_num INT,
  is_top TINYINT(1),
  content TEXT);
--完整性约束条件之主键约束(一张表只能有一个主键,非空且唯一,主键类型不一定是非整型)
--单字段主键
CREATE TABLE users(id INT PRIMARY KEY ,
name VARCHAR(20),
city VARCHAR(20));
--多字段联合主键
CREATE TABLE users2(
  id INT,
  name VARCHAR(20),
  city VARCHAR(20),
  PRIMARY KEY (name,id));

--表记录操作
--表记录之增、删、改
--增加一条记录
CREATE TABLE employee_new(
  id INT PRIMARY KEY  AUTO_INCREMENT,
  name VARCHAR(20) not null unique,
  birthday VARCHAR(20),
  salary FLOAT(7,2));
INSERT INTO employee_new(id, name, birthday, salary) VALUES
  (1,'yuan','1990-09-09',9000);
INSERT INTO employee_new  VALUES (2,'吴西平','1988-08-07',10000);
INSERT INTO employee_new (name,salary)VALUES ('xialv',1000);
--插入多条数据
INSERT into employee_new values(4,'alvin1','1993-04-20',3000),
(5,'alvin2','1995-05-12',5000);
INSERT INTO employee_new SET id=12,name='alvin3'; --set 插入法
--修改表记录
UPDATE employee_new SET birthday='1989-10-24' WHERE id=1;
--将yuan的薪水在原有的基础上增加1000元
UPDATE employee_new SET salary=salary+1000 where name='yuan';
--删除表记录(delete from employee_new WHERE ...)
--删除表中名称为alex的记录
DELETE FROM employee_new WHERE name='alex';
--删除表中所有记录
DELETE from employee_new;
--使用truncate删除表中的记录
TRUNCATE table employee_new;

--表记录之查询(单表查询)
--查询表达式
   SELECT *|field1,filed2 ...   FROM tab_name
                  WHERE 条件
                  GROUP BY field
                  HAVING 筛选
                  ORDER BY field
                  LIMIT 限制条数
CREATE TABLE ExamResult(id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
JS DOUBLE,
Django DOUBLE,
OpenStack DOUBLE);
INSERT INTO ExamResult VALUES (1,'yuan',98,98,98),
  (2,'xialv',35,98,67),
  (3,'alex',59,59,62),
  (4,'wusir',88,89,82),
  (5,'alvin',88,98,67),
  (6,'yuan',86,100,55);
--查询表中所有学生的信息
SELECT * FROM ExamResult;
--过滤表中的重复数据
SELECT DISTINCT JS FROM ExamResult;
--查询表中所有学生的姓名和对应的JS成绩
SELECT name,JS FROM ExamResult;
--SELECT 也可以使用表达式,并且可以使用:字段 as 别名或者:字段 别名
SELECT name,JS+10,Django+10,OpenStack+10 FROM ExamResult;
--统计每个学生的总分
SELECT name,JS+Django+OpenStack FROM ExamResult;
--使用别名表示学生总分
SELECT name as 姓名,JS+Django+OpenStack as 总成绩 FROM ExamResult;
select name ,JS+Django+OpenStack 总成绩 FROM ExamResult;
SELECT name JS FROM ExamResult;--记得加逗号

--使用where子句,进行过滤查询
--查询姓名为yuan的学生成绩
SELECT * from ExamResult WHERE name='yuan';
--查询JS成绩大于90分的同学
SELECT id,name,JS FROM ExamResult WHERE JS>90;
--查询总分大于200分的同学
SELECT name,JS+Django+OpenStack as 总成绩 FROM ExamResult WHERE JS+Django+OpenStack>200;
--查询JS分数在70——100之间的同学
SELECT name,JS FROM ExamResult WHERE JS BETWEEN 70 AND 100;
--查询Django分数为75,98,77的同学
SELECT name,Django FROM ExamResult WHERE Django in (75,98,77);
--查询所有姓王的学生的成绩
SELECT * FROM ExamResult WHERE name like '王%';(如果是%则表示任意多字符,此例如唐僧,唐国强
                        如果是_则表示一个字符唐_,只有唐僧符合。两个_则表示两个字符:__)
--查询JS>90,Django>90的同学
SELECT id,name FROM ExamResult WHERE JS>90 AND Django>90;
--查询缺考数学的学生姓名
SELECT name FROM ExamResult WHERE JS is NULL ;

--order by 指定排序的列,排序的列即可是表中的列名,也可以是select语句后制定的别名
--Asc升序、Desc 降序,其中asc为默认值 order by 子句应位于select 语句的结尾
--对JS成绩排序后输出
SELECT * FROM ExamResult ORDER BY JS;
--对总分排序后从高到底的顺序输出
SELECT name,JS+Django+OpenStack as 总成绩 FROM ExamResult ORDER BY 总成绩 DESC ;
--对姓李学生成绩排序输出
SELECT name,JS+Django+OpenStack as 总成绩 FROM ExamResult WHERE name LIKE 'a%' ORDER BY 总成绩 DESC ;

--group by 分组查询
CREATE TABLE order_menu(id INT PRIMARY KEY AUTO_INCREMENT,
product_name VARCHAR(20),
price FLOAT(6,2),
born_date DATE,
class VARCHAR(20));
INSERT INTO order_menu (product_name,price,born_date,class) VALUES
                                             ("苹果",20,20170612,"水果"),
                                             ("香蕉",80,20170602,"水果"),
                                             ("水壶",120,20170612,"电器"),
                                             ("被罩",70,20170612,"床上用品"),
                                             ("音响",420,20170612,"电器"),
                                             ("床单",55,20170612,"床上用品"),
                                             ("草莓",34,20170612,"水果");
--group by 字句,其后可以接多个列名,也可以跟having子句,对group by的结果进行筛选
--按位置字段进行筛选
select * from order_menu group by 5;
--对购物表按类名分组后显示每一组商品的价格总和
SELECT class,sum(price) from order_menu GROUP BY class;
--对购物表按类名分组后显示每一组商品价格总和超过150的商品
SELECT class,sum(price) from order_menu GROUP BY class HAVING sum(price)>150;
--注意:having 和 where两者都可以对查询结果进行进一步的过滤,差别有:
                     <1>where语句只能用在分组之前的筛选,having可以用在分组之后的筛选;
                     <2>使用where语句的地方都可以用having进行替换
                     <3>having中可以用聚合函数,where中就不行。
--group_concat()函数
SELECT id,group_concat(name),group_concat(JS) FROM ExamResult group by id;
--聚合函数(先把要求的内容查出来再包上聚合函数即可)
--统计表中所有记录
--COUNT(列名)统计行的个数
--统计一个班有多少学生,先查出所有学生,再用count包上
select count(*) from ExamResult;
--统计JS成绩大于70的学生有多少个
select count(JS) from ExamResult where JS>70;
--统计总分大于280的人数有多少个
select count(name) from ExamResult where JS+Django+OpenStack>280;

--SUM(列名):统计满足条件的行的内容和
--统计一个班JS的总成绩,先查出所有JS成绩,再用SUM包上
SELECT sum(JS) AS JS总成绩 FROM ExamResult;
--统计一个班各科分别的总成绩
select sum(JS)AS JS总成绩,sum(Django) AS Django总成绩,sum(OpenStack) AS OpenStack总成绩 FROM ExamResult;
--统计一个班各科的成绩总和
select sum(ifnull(JS,0)+ifnull(Django,0),+ifnull(OpenStack,0)) AS 总成绩 FROM ExamResult;
SELECT sum(JS+OpenStack+Django) AS 总成绩 FROM ExamResult;
--统计一个班JS成绩平均分
SELECT sum(JS)/count(*) FROM ExamResult;

--AVG(列名)
--求一个班级JS平均分?先查出所有JS分,然后用avg包上
SELECT avg(JS) FROM ExamResult;
--求一个班级总分平均分
SELECT avg(JS+Django+OpenStack) FROM ExamResult;
SELECT avg((ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))) FROM ExamResult;

--max,min
--求班级最高分和最低分(数值范围在统计中特别有用)
SELECT max(ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)) 最高分 FROM ExamResult;
SELECT min(ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)) 最低分 FROM ExamResult;
--求购物表中单价最高的商品名称及价格
SELECT id,max(price) FROM order_menu;
SELECT max(price) FROM order_menu;
--注意
Mysql在执行sql语句时的执行顺序:
                -- from  where  select group by  having order by
分析:
SELECT JS as JS成绩 FROM ExamResult WHERE JS成绩>90;不成功
SELECT JS as JS成绩 FROM ExamResult HAVING JS成绩>90;--成功
--limit
SELECT * FROM ExamResult LIMIT 2; --按顺序显示两条记录
SELECT * FROM ExamResult LIMIT 2,3;--跳过前两条显示接下来的三条记录
SELECT * FROM ExamResult LIMIT 2,2;
--使用正则表达式查询
SELECT * FROM ExamResult WHERE name REGEXP 'yu';
SELECT * FROM ExamResult WHERE name REGEXP 'yun$';
SELECT * FROM ExamResult WHERE name REGEXP 'm{2}';

--外键约束
创建外键
--每一个班主任会对应多个学生,而每一个学生只能对应一个班主任
--主表
create table ClassCharger(
  id tinyint primary key auto_increment,
  name VARCHAR(20),
  age INT,
  is_married boolean
);
insert into ClassCharger(name, age, is_married) VALUES ('冰冰',12,0),
  ('丹丹',14,0),
  ('歪歪',22,0),
  ('姗姗',20,0),
  ('小雨',21,0);
--子表(--作为外键一定要和关联主键的数据类型保持一致)
create table Student(
  id INT PRIMARY KEY AUTO_INCREMENT,
  name  VARCHAR(20),
  charger_id TINYINT) ENGINE =innodb;
INSERT INTO Student(name,charger_id) VALUES ("alvin1",2),
                                            ("alvin2",4),
                                            ("alvin3",1),
                                            ("alvin4",3),
                                            ("alvin5",1),
                                            ("alvin6",3),
                                            ("alvin7",2);
--增加和删除外键
alter table Student ADD constraint abc foreign key (charger_id) references ClassCharger(id);
alter TABLE Student drop FOREIGN KEY abc;

--多表查询
CREATE DATABASE aggressive2020 CHARACTER SET utf8;
create table employee(emp_id INT primary key not null,
emp_name varchar(50),
age int,
dept_id int);
INSERT into employee(emp_id,emp_name,age,dept_id)VALUES (1,'A',19,200),
  (2,'B',26,201),
  (3,'C',30,201),
  (4,'D',24,202),
  (5,'E',20,200),
  (6,'F',38,204);
create table department(
       dept_id int,
       dept_name varchar(100));
insert into department values
  (200,'人事部'),
  (201,'技术部'),
  (202,'销售部'),
  (203,'财政部');
--内连接:仅选出两张表中互相匹配的记录,而外连接会先出其他不匹配的记录,最常用的是内连接
-- select * from employee,department where employee.dept_id = department.dept_id;
--select * from employee inner join department on employee.dept_id = department.dept_id;
外连接:
左连接:包含所有左边表中的记录甚至是右边表中没有和它匹配的记录
右连接:包含所有右边表中的记录甚至是左边表中没有和它匹配的记录
全外连接:在内连接的基础上增加左边有右边没有和右边有左边没有的结果
select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id
   UNION
   select * from employee LEFT JOIN department on employee.dept_id = department.dept_id;
多表查询之复合条件查询
--查询员工年龄大于等于25的部门
select distinct dept_name from employee,department where
  employee.dept_id =department.dept_id AND age>25;
--以内连接的方式查询employee和department表,并且以age字段升序方式显示
SELECT * FROM employee,department WHERE employee.dept_id=department.dept_id ORDER BY age ASC ;

--多表查询之子查询
--查询employee表,但dept_id必须在department表中出现过
select * from employee WHERE dept_id in (SELECT dept_id FROM department);
--查询员工年龄大于等于25岁的部门
select dept_id,dept_name FROM department WHERE dept_id IN (
  SELECT DISTINCT dept_id FROM employee WHERE age>25);

select * FROM employee WHERE exists(SELECT dept_name FROM department
WHERE dept_id=205);
原文地址:https://www.cnblogs.com/wuxiping2019/p/11421743.html