Day11 数据库的基本语法(偏重于查询)

数据库的介绍:

老师博客:
MYSQL-1 - Yuan先生 - 博客园 http://www.cnblogs.com/yuanchenqi/articles/7269675.html
作业地址:
http://www.cnblogs.com/yuanchenqi/articles/7282845.html

  

  简单的数据可以利用文本来保存,但如果数据比较复杂的话(比如说工资表),就需要利用数据库来保存了。

  数据库就是一个存储数据的仓库。

可以这样去理解:

  数据库就像一个文件夹

  数据表就像一个文件

  表记录就像里边记录的内容

目前常用的数据库管理软件:

  mysql  oracle  sqlserver


数据库操作:

数据库相关的命令:

数据库操作命令:

#显示所有的数据库
show databases;

#创建一个数据库,[]内的是可以添加也可以不添加的
create database  database_name [character set utf8] ;

#展示创建数据库的信息
show create database  database_name;

#进入某个数据库
use database_name;

#可以进行折行操作,不加分号无法执行.

#修改数据库的某些属性(不能改数据的名字)
alter database database_name [character set utf8];

#删除数据库
drop database database_name;

#进入到某个数据库后显示数据库的名字;
select database();

数据表操作:

#创建一个表
create table table_name (
    字段filed    字段类型    [完整性约束],
    字段filed    字段类型    [完整性约束]
    );
#完整性约束是就是对于字段的约束
#非空,uniqe(唯一约束,不能重复)
#创建多个字段要加逗号


#查看表结构
desc    table_name;


#查看创建表的信息;
show create table table_name;

#展示所有表名
show tables;

#修改表
alter table table_name   add       field   type 完整性约束 [first | after tfield] #增加一个字段
alter table table_name   modify    field   type 完整性约束
alter table table_name   change    field   type 完整性约束
alter table table_name   drop      field   type 完整性约束

#删除表
drop table_name;

#设置id自增,例子

#alter table c1modify id int primary key auto_incroment first;

完整性约束:

主键约束:

  primray key:非空 (not null ) 且唯一 (uniqe)

  只能有一个主键

表记录操作:

#增加记录

    insert [into] tab_name (field1,field2....) values (values1,values2....),
                                                                     (values1,values2....),
                                                                                              ... ; 

    insert table_name set field=value;

    #修改表记录

    update tab_name set field=values where 条件;

    #删除记录

    delete from table_name where 条件;    #删除数据记录

    truncate table_name;                         #整个表删了,重新按照表字段生成空表

    #数据量多,用truncate    数据少,用delect

    查询表记录:重要

    select * from table_name;    #显示所有记录的所有字段

CREATE TABLE emp(
    id       INT PRIMARY KEY AUTO_INCREMENT,
    name     VARCHAR(20),
    gender   ENUM("male","female","other"),
#E#NUM枚举类型,后面放几组内容,插入数据只能插入定义好的机组内容
    age      TINYINT,
    dep      VARCHAR(20),
    city     VARCHAR(20),
   salary    DOUBLE(7,2)
);


INSERT INTO emp (name,gender,age,dep,city,salary) VALUES
                ("yuan","male",24,"教学部","河北省",8000),
                ("egon","male",34,"保安部","山东省",8000),
                ("alex","male",28,"保洁部","山东省",10000),
                ("景丽阳","female",22,"教学部","北京",9000),
                ("张三", "male",24,"教学部","河北省",6000),
                ("李四", "male",32,"保安部","北京",12000),
                ("王五", "male",38,"教学部","河北省",7000),
                ("赵六", "male",19,"保安部","河北省",9000),
                ("猪七", "female",24,"保洁部","北京",9000);

SELECT  * FROM emp;

#将查询的内容以别名的方式显示出来;

eg:select name as 姓名,salary as 薪水 from emp;

where语句的语法:

-- where字句中可以使用:

         -- 比较运算符:
                        > < >= <= <> !=
                        between 80 and 100 值在80到100之间
                        in(80,90,100) 值是80或90或100
                        like 'yuan%'
                        /*
                        pattern可以是%或者_,
                        如果是%则表示任意多字符,此例如唐僧,唐国强
                        如果是_则表示一个字符唐_,只有唐僧符合。两个_则表示两个字符:__
                        */

         -- 逻辑运算符
                        在多个条件直接可以使用逻辑运算符 and or not

分组group by:

后边要加的是分组的内容,前边查询的时候第一位是分组内容,第二位是想要怎么查

比如说查询每个部门的人数:

max,avg,min(大,平均,小)

select dep,count(id) from emp group by dep;

查看每一个性别对应多少人:

select gender,count(*) from  emp group by gender;

查看每个省的平均工资;

select city,avg(salary) from emp group by city;

-- 语法:
  SELECT column_name, function(column_name)
        FROM table_name
        WHERE column_name operator value
        GROUP BY column_name;



-- 查询男女员工各有多少人
 
SELECT gender 性别,count(*) 人数 FROM emp5 GROUP BY gender;
 
-- 查询各个部门的人数
 
SELECT dep 部门,count(*) 人数 FROM emp5 GROUP BY dep;
 
-- 查询每个部门最大的年龄
 
SELECT dep 部门,max(age) 最大年纪 FROM emp5 GROUP BY dep;
 
-- 查询每个部门年龄最大的员工姓名
 
SELECT * FROM emp5 WHERE age in (SELECT max(age) FROM emp5 GROUP BY dep);
 
-- 查询每个部门的平均工资
 
SELECT dep 部门,avg(salary) 最大年纪 FROM emp GROUP BY dep;
 
--  查询教学部的员工最高工资:
 
SELECT dep,max(salary) FROM emp11 GROUP BY dep HAVING dep="教学部";
 
-- 查询平均薪水超过8000的部门
 
SELECT dep,AVG(salary) FROM  emp GROUP BY dep HAVING avg(salary)>8000;
 
--  查询每个组的员工姓名
SELECT dep,group_concat(name) FROM emp GROUP BY dep;
 
-- 查询公司一共有多少员工(可以将所有记录看成一个组)
 
SELECT COUNT(*) 员工总人数 FROM emp;
 
                  -- KEY: 查询条件中的每个后的词就是分组的字段

  

having  子句:(过滤)

求平均工资最高省份的名称,这时候不能光用分组,相当于对分组后的信息做筛选。

select city,avg(salary) from emp group by city having   avg(salary) > 8000;

order  by:(按照。。排序)

按照工资排序(默认从小到大)

select * from emp order by salary;

-- 语法:

select *|field1,field2... from tab_name order by field [Asc|Desc]

         -- Asc 升序、Desc 降序,其中asc为默认值 ORDER BY 子句应位于SELECT语句的结尾。

  

limit :

SELECT * from ExamResult limit 1;          --  取出查询出来的数据前面的第几条
SELECT * from ExamResult limit 2,5;        --  跳过前两条显示接下来的五条纪录
SELECT * from ExamResult limit 2,2;

  

group_concat(name):将符合的结果拼接起来

#选出每个部门的都有哪些人:

select dep,group_concat(name) from emp group by dep;


多表查询:

有时候数据可能不止在一张表中,可能需要多个表的数据查询;

#创建两个有关联的表

CREATE TABLE emp(
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(20),
    salary DOUBLE(7,2),
    dep_id INT
);

INSERT INTO emp (name,salary,dep_id) VALUES ("张三",8000,2),
                                            ("李四",12000,1),
                                            ("王五",5000,2),
                                            ("赵六",8000,3),
                                            ("猪七",9000,1),
                                            ("周八",7000,4),
                                            ("蔡九",7000,2);

CREATE TABLE dep(
      id INT PRIMARY KEY AUTO_INCREMENT,
      name VARCHAR(20)
);


INSERT INTO dep (name) VALUES ("教学部"),
                              ("销售部"),
                              ("人事部");

#这样查询的话显示的是表1和表2的乘机,也就是笛卡尔积  

select * from emp.dep;

#想要将两个表组合起来,需要加where条件

select * from emp.dep where emp.dep_id=dep.id;

#多表联合查询

select dep.name,emp.name from emp,dep where emp.dep_id=dep.id and emp.name="张三";

查询销售部的张三

内连接查询:

select * from emp inner join dep on emp.dep_id = dep.id;

外连接查询:

左外连接:

select * from emp left join dep on emp.dep_id = dep.id;

以左边为主,左边有的必须有

右外连接:

select * from emp right join dep on emp.dep_id = dep.id;

以右边为主,不能有空数据


完整性约束:

唯一约束:

唯一约束可以有多个但索引列的值必须唯一,索引列的值允许有空值。

CREATE TABLE t5(
  id   INT AUTO_INCREMENT,
  name VARCHAR(20) DEFAULT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY UK_t5_name (name)
);
-- 建表后添加约束:

alter table t5 add constraint UK_t5_name unique (name);
#constraint:这里的constraint是约束的意思
#name:是字段的名称 -- 如果不需要唯一约束,则可以这样删除 ALTER TABLE t5 DROP INDEX UK_t5_name;

  

自增约束:

MySQL 每张表只能有1个自动增长字段,这个自动增长字段通常作为主键,也可以用作非主键使用,但是请注意将自动增长字段当做非主键使用时必须必须为其添加唯一索引,否则系统将会报错。

#自增约束必须是一个数字类型。

auto_increment不一定非作为主键使用,但是不作为主键的时候使用时必须作为唯一索引,后则将报错。

mysql> CREATE TABLE t4(
    ->   id INT NOT NULL,
    ->   name VARCHAR(20),
    ->   age INT AUTO_INCREMENT
    -> );


ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key




#可以改为:
mysql> CREATE TABLE t4(
    ->   id INT NOT NULL,
    ->   name VARCHAR(20),
    ->   age INT UNIQUE AUTO_INCREMENT
    -> );
Query OK, 0 rows affected (0.13 sec)

  

如果在创建表的时候不设置主键,那么系统会自动寻找非空且唯一的作为主键。

复合主键:

个人的理解就是将两个键同时作为主键,只要两个键不同时一样就是可以的。

所谓的复合主键 就是指你表的主键含有一个以上的字段。

如果一列不能唯一区分一个表里的记录时,可以考虑多个列组合起来达到区分表记录的唯一性,形式 

①创建时:

create table sc (
    studentid int,
    courseid int,
    score int,
primary key (studentno,courseid)
);        
②修改时:

alter table tb_name add primary key (字段1,字段2,字段3);

  

表与表的关系:

一对一:比如说一个身份证号对应一个人名

    可以将关联字段设置在任意位置,将关联字段设为Uniqe

一对多:比如说一个部门对应多个人

    将关联字段设置在多的表里边

多对多:一个学生属于多个老师,一个老师对应多个学生

    一般创建第三张来解决这个问题,将多个关系分别对应起来。

    

原文地址:https://www.cnblogs.com/sexiaoshuai/p/7504057.html