数据库操作:

---查看warnings内容
show warnings

---查看当前在那个数据库
select database();

---查看有那些数据库
show databases;

---查看数据库创建信息
show create database s3;

---创建数据库
create database if not exists s3;

---创建数据库 设置编码
create database if not exists s4 character set utf8;

---修改数据库编码
alter database s4 character set gbk;

---删除数据库
drop database s4;

创建表

/////////////表处理(主键:非空且唯一) 非空:not null 唯一:unique float(4,2)表示6位数,小数点数2位 最大99.99
---创建表
create table emp(
id INT primary KEY auto_increment,
name VARCHAR(30),
age TINYINT DEFAULT 100,
salary FLOAT(9,2)
);

 

---多字段联合主键
create table users2(
id INT,
name varchar(20),
city varchar(20),
primary key(name,id)
);

 

查看表信息

---查看表创建信息
desc tab_name 查看表结构
show columns from tab_name 查看表结构
show tables 查看当前数据库中的所有的表
show create table tab_name 查看当前数据库表建表语句


修改表信息

----修改表结构
--增加列(字段) alter table tab_name add [column] 列名 类型[完整性约束条件][first|after 字段名];
ALTER TABLE emp ADD address TEXT;
#添加多个字段
ALTER TABLE emp ADD date DATE not NULL,ADD work VARCHAR(22) not NULL;

--删除列
alter TABLE emp DROP WORK; 删除work 字段
#删除多个字段
alter TABLE emp DROP date,DROP address;

--修改字段属性
ALTER TABLE emp MODIFY age SMALLINT NOT NULL; #age字段类型修改成SMALLINT NOT NULL
#修改到那个字段后面[first|after 字段名] 放到第一 after 放到那个字段后面
ALTER TABLE emp MODIFY age SMALLINT NOT NULL AFTER id; #AFTER id放到ID 后面

--修改列名
alter table tab_name change [column] 列名 新列名 类型 [完整性约束条件][first|after 字段名];
ALTER TABLE emp CHANGE age uuid VARCHAR(20) not null; #age 修改成uuid


--修改表明
RENAME TABLE emp to emppp;

--添加主键,删除主键
alter table tab_name add primary key(字段名称,...)
alter table users drop primary key;

eg:
mysql> create table test5(num int auto_increment);
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
create table test(num int primary key auto_increment);
-- 思考,如何删除主键?
alter table test modify id int; -- auto_increment没了,但这样写主键依然存在,所以还要加上下面这句
alter table test drop primary key;-- 仅仅用这句也无法直接删除主键

--唯一索引
alter table tab_name add unique [index|key] [索引名称](字段名称,...)

alter table users add unique(name)-- 索引值默认为字段名show create table users;
alter table users add unique key user_name(name);-- 索引值为user_name

-- 添加联合索引
alter table users add unique index name_age(name,age);#show create table users;

-- 删除唯一索引
alter table tab_name drop {index|key} index_name
 
--插入表数据
INSERT into emp(name,salary) VALUES("张三丰",1900.99);
INSERT into emp set name="黑墨水"
#插入多行
INSERT into emp(name,salary) VALUES("张三丰",1900.99),("张无忌",2900.99);
--更新
UPDATE emp set salary=salary+20000 WHERE name="张无忌"; #salary=salary+20000(salary是原来存在的数据在加上20000)
#修改多个字段
UPDATE emp set salary=salary+20000,name="一天" WHERE name="张无忌"

---删除表数据
DELETE FROM emp; #删除所有数据 (TRUNCATE TABLE emp)
DELETE FROM emp WHERE name="一天"
DELETE FROM emp WHERE id=2 and name="张三丰"
DELETE FROM emp WHERE id=2 OR name="张三丰"

表查询
SELECT id,name as 肚子 FROM emp #查询id  name
SELECT DISTINCT name FROM emp ; #DISTINCT 给name字段去除重复的内容
#别名
SELECT DISTINCT name as 肚子 FROM emp

--%
SELECT id,name FROM emp WHERE salary like 'yuan%'
/*
pattern可以是%或者_,
如果是%则表示任意多字符,此例如唐僧,唐国强
如果是_则表示一个字符唐_,只有唐僧符合。两个_则表示两个字符:__
*/


--大于查询出来
SELECT id,name FROM emp WHERE salary > 100;

--查找区间
SELECT id,name FROM emp WHERE salary BETWEEN 80 and 90 #between 80 and 100 值在10到20之间

--值包含这些的
SELECT id,name FROM emp WHERE salary in (80,90,200) # in(80,90,100) 值是10或20或30

--查询空的
SELECT id,name FROM emp WHERE salary=null; #这个无法查询
SELECT id,name FROM emp WHERE salary is null; 用这个查询空

--升序排序
SELECT id,name FROM emp WHERE ORDER BY id; #按id
SELECT id,name FROM emp WHERE id > 100 ORDER BY id; #按id

--降序
SELECT id,name FROM emp WHERE id > 100 ORDER BY id desc; #按id

--2个字段的相加
SELECT age+salary FROM emp; #age+salary 2个字段相加
SELECT age+salary FROM emp ORDER BY age+salary desc; #age+salary降序排
SELECT age+salary as test FROM emp ORDER BY test desc;

重点:Select from where group by having order by 这些过滤条件执行顺序
-- Mysql在执行sql语句时的执行顺序:
-- 先执行 from ---> where ---> select ---> group by ---> having ---> order by
-- 分析:
select JS as JS成绩 from ExamResult where JS成绩 >70; ---- 不成功
select JS as JS成绩 from ExamResult having JS成绩 >90; --- 成功


---分组
-- 注意,按分组条件分组后每一组只会显示第一条记录(也就说如果按name分类了,那name中有3个叫张三丰的,只会显示第一条记录,另外两条记录给里分离到第一条里面去了)
-- group by字句,其后可以接多个列名,也可以跟having子句,对group by 的结果进行筛选。

--按第二个字段进行分组
SELECT * FROM emp GROUP BY 2

--按name分组 然后计算salary的和
SELECT `name`,SUM(salary) FROM emp GROUP BY name;#解析 name 分组后只会显示第一条记录,然后计算sum计算统计这时候 有3个张珊分到一个组里面会算出 所有是30000
 结果:

 

--HAVING分组后过滤条件 不能使用where   where是在分组之前过滤
SELECT `name`,SUM(salary) FROM emp GROUP BY name HAVING SUM(salary) > 20000;
/*
having 和 where两者都可以对查询结果进行进一步的过滤,差别有:
<1>where语句只能用在分组之前的筛选,having可以用在分组之后的筛选;
<2>使用where语句的地方都可以用having进行替换
<3>having中可以用聚合函数,where中就不行。
*/
-- (6)聚合函数: 先不要管聚合函数要干嘛,先把要求的内容查出来再包上聚合函数即可。
-- (一般和分组查询配合使用)

--<1> 统计表中所有记录

-- COUNT(列名):统计行的个数
-- 统计一个班级共有多少学生?先查出所有的学生,再用count包上
select count(*) from ExamResult;
-- 统计JS成绩大于70的学生有多少个?
select count(JS) from ExamResult where JS>70;
-- 统计总分大于280的人数有多少?
select count(name) from ExamResult
where (ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0))>280;
-- 注意:count(*)统计所有行; count(字段)不统计null值.

-- SUM(列名):统计满足条件的行的内容和
-- 统计一个班级JS总成绩?先查出所有的JS成绩,再用sum包上
select JS as JS总成绩 from ExamResult;
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(Database,0))
as 总成绩 from ExamResult;
-- 统计一个班级JS成绩平均分
select sum(JS)/count(*) from ExamResult ;
-- 注意:sum仅对数值起作用,否则会报错。

-- AVG(列名):
-- 求一个班级JS平均分?先查出所有的JS分,然后用avg包上。
select avg(ifnull(JS,0)) from ExamResult;
-- 求一个班级总分平均分
select avg((ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,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;--id和最高价商品是一个商品吗?

SELECT MAX(price) FROM order_menu;

-- 注意:null 和所有的数计算都是null,所以需要用ifnull将null转换为0!
-- -----ifnull(JS,0)


-- with rollup的使用

--<2> 统计分组后的组记录

---外键
---  每一个班主任会对应多个学生 , 而每个学生只能对应一个班主任

----主表

CREATE TABLE ClassCharger(

       id TINYINT PRIMARY KEY auto_increment,
       name VARCHAR (20),
       age INT ,
       is_marriged boolean  -- show create table ClassCharger: tinyint(1)

);

INSERT INTO ClassCharger (name,age,is_marriged) 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,     --切记:作为外键一定要和关联主键的数据类型保持一致
FOREIGN KEY (charger_id) REFERENCES ClassCharger(id), 关联外建 charger_id字段当前表 到 classcharger表的id字段
-- ADD CONSTRAINT charger_fk_stu FOREIGN KEY (charger_id) REFERENCES ClassCharger(id) ##给外建加名字 ADD CONSTARAINT charger_fk_stu 这段是自己加上外键名字 ) ENGINE=INNODB; INSERT INTO Student(name,charger_id) VALUES ("alvin1",2), ("alvin2",4), ("alvin3",1), ("alvin4",3), ("alvin5",1), ("alvin6",3), ("alvin7",2); DELETE FROM ClassCharger WHERE name="冰冰"; INSERT student (name,charger_id) VALUES ("yuan",1); -- 删除居然成功,可是 alvin3显示还是有班主任id=1的冰冰的; -----------增加外键和删除外键--------- ALTER TABLE student ADD CONSTRAINT abc FOREIGN KEY(charger_id) REFERENCES classcharger(id); ALTER TABLE student DROP FOREIGN KEY abc;

--外键约束对子表的含义:   如果在父表中找不到候选键,则不允许在子表上进行insert/update

--外键约束对父表的含义:    在父表上进行update/delete以更新或删除在子表中有一条或多条对
                    -- 应匹配行的候选键时,父表的行为取决于:在定义子表的外键时指定的
                    -- on update/on delete子句


-----------------innodb支持的四种方式---------------------------------------

-----cascade方式 在父表上update/delete记录时,同步update/delete掉子表的匹配记录
-----外键的级联删除:如果父表中的记录被删除,则子表中对应的记录自动被删除--------

     FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
                              ON DELETE CASCADE  #主表删除字表里面的数据也跟着删除


------set null方式 在父表上update/delete记录时,将子表上匹配记录的列设为null
   -- 要注意子表的外键列不能为not null

     FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)
                              ON DELETE SET NULL #主表删掉后,字表里面的记录变成null值 不会报错.


------Restrict方式 :拒绝对父表进行删除更新操作(了解)

------No action方式 在mysql中同Restrict,如果子表中有匹配的记录,则不允许对父表对应候选键
   -- 进行update/delete操作(了解)

多表查询:

 

内连接查询

-- 准备两张表
-- company.employee
-- company.department

      create table employee(
      emp_id int auto_increment primary key not null,
      emp_name varchar(50),
      age int,
      dept_id int
      );

      insert into employee(emp_name,age,dept_id) values
        ('A',19,200),
        ('B',26,201),
        ('C',30,201),
        ('D',24,202),
        ('E',20,200),
        ('F',38,204);


    create table department(
       dept_id int,
       dept_name varchar(100)
      );

    insert into department values
      (200,'人事部'),
      (201,'技术部'),
      (202,'销售部'),
      (203,'财政部');

mysql> select * from employee;
+--------+----------+------+---------+
| emp_id | emp_name | age  | dept_id |
+--------+----------+------+---------+
|      1 | A        |   19 |     200 |
|      2 | B        |   26 |     201 |
|      3 | C        |   30 |     201 |
|      4 | D        |   24 |     202 |
|      5 | E        |   20 |     200 |
|      6 | F        |   38 |     204 |
+--------+----------+------+---------+
rows in set (0.00 sec)

mysql> select * from department;
+---------+-----------+
| dept_id | dept_name |
+---------+-----------+
|     200 | 人事部    |
|     201 | 技术部    |
|     202 | 销售部    |
|     203 | 财政部    |
+---------+-----------+
rows in set (0.01 sec)

查询A在那个部门
SELECT * FROM department,employee WHERE employee.emp_name = "A" AND  employee.dept_id = department.dept_id
或者:
SELECT * FROM employee INNER JOIN department  on employee.emp_name = "A" AND  employee.dept_id = department.dept_id
都是一样的

 外连接查询


--(1)左外连接:在内连接的基础上增加左边有右边没有的结果 也就是说主表为左边的上的数据全部显示出来,右边表上面如果没有匹配上就显示空置

 select * from employee left join department on employee.dept_id = department.dept_id;

     +--------+----------+------+---------+---------+-----------+
    | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
    +--------+----------+------+---------+---------+-----------+
    |      1 | A        |   19 |     200 |     200 | 人事部    |
    |      5 | E        |   20 |     200 |     200 | 人事部    |
    |      2 | B        |   26 |     201 |     201 | 技术部    |
    |      3 | C        |   30 |     201 |     201 | 技术部    |
    |      4 | D        |   24 |     202 |     202 | 销售部    |
    |      6 | F        |   38 |     204 |    NULL | NULL      |
    +--------+----------+------+---------+---------+-----------+

 --(2)右外连接:在内连接的基础上增加右边有左边没有的结果

 select * from employee RIGHT JOIN department on employee.dept_id = department.dept_id;

        +--------+----------+------+---------+---------+-----------+
        | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
        +--------+----------+------+---------+---------+-----------+
        |      1 | A        |   19 |     200 |     200 | 人事部    |
        |      2 | B        |   26 |     201 |     201 | 技术部    |
        |      3 | C        |   30 |     201 |     201 | 技术部    |
        |      4 | D        |   24 |     202 |     202 | 销售部    |
        |      5 | E        |   20 |     200 |     200 | 人事部    |
        |   NULL | NULL     | NULL |    NULL |     203 | 财政部    |
        +--------+----------+------+---------+---------+-----------+

 --(3)全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果

    -- mysql不支持全外连接 full JOIN
    -- mysql可以使用此种方式间接实现全外连接
    
   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;

        

        +--------+----------+------+---------+---------+-----------+
        | emp_id | emp_name | age  | dept_id | dept_id | dept_name |
        +--------+----------+------+---------+---------+-----------+
        |      1 | A        |   19 |     200 |     200 | 人事部    |
        |      2 | B        |   26 |     201 |     201 | 技术部    |
        |      3 | C        |   30 |     201 |     201 | 技术部    |
        |      4 | D        |   24 |     202 |     202 | 销售部    |
        |      5 | E        |   20 |     200 |     200 | 人事部    |
        |   NULL | NULL     | NULL |    NULL |     203 | 财政部    |
        |      6 | F        |   38 |     204 |    NULL | NULL      |
        +--------+----------+------+---------+---------+-----------+

      -- 注意 union与union all的区别:union会去掉相同的纪录

 

 

-- 查询员工年龄大于等于25岁的部门

    SELECT DISTINCT department.dept_name
    FROM employee,department
    WHERE employee.dept_id = department.dept_id
    AND age>25;


--以内连接的方式查询employee和department表,并且以age字段的升序方式显示

    select employee.emp_id,employee.emp_name,employee.age,department.dept_name
    from employee,department
    where employee.dept_id = department.dept_id
    order by age asc;

 

 子查询

 

-- 子查询是将一个查询语句嵌套在另一个查询语句中。
-- 内层查询语句的查询结果,可以为外层查询语句提供查询条件。
-- 子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
-- 还可以包含比较运算符:= 、 !=、> 、<等


-- 1. 带IN关键字的子查询

   ---查询employee表,但dept_id必须在department表中出现过

   select * from employee
            where dept_id IN
            (select dept_id from department);


+--------+----------+------+---------+
| emp_id | emp_name | age  | dept_id |
+--------+----------+------+---------+
|      1 | A        |   19 |     200 |
|      2 | B        |   26 |     201 |
|      3 | C        |   30 |     201 |
|      4 | D        |   24 |     202 |
|      5 | E        |   20 |     200 |
+--------+----------+------+---------+
rows in set (0.01 sec)



-- 2. 带比较运算符的子查询
      --      =、!=、>、>=、<、<=、<>

     -- 查询员工年龄大于等于25岁的部门
     select dept_id,dept_name from department
           where dept_id IN
          (select DISTINCT dept_id from employee where age>=25);

-- 3. 带EXISTS关键字的子查询

-- EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
-- 而是返回一个真假值。Ture或False
-- 当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询

     select * from employee
              WHERE EXISTS
              (SELECT dept_name from department where dept_id=203);#(SELECT dept_name from department where dept_id=203)这句是返回如果是真 就继续执行select * from employee 不然就不执行了
--department表中存在dept_id=203,Ture select * from employee WHERE EXISTS (SELECT dept_name from department where dept_id=205); -- Empty set (0.00 sec)  ps: create table t1(select * from t2); 拷贝表

 

 

 

 

 

 

 

 

 

posted on 2018-07-02 13:23  Python哥  阅读(158)  评论(0编辑  收藏  举报