數據庫總結

1、數據庫的簡介

  1.數據庫mysql

  數據庫(database,DB)是指長期存儲在計算機內的,有組織,可共享的數據的集合。數據庫中的數據按必定的數字模型組織、描述和存儲,具備較小的冗餘,較高的數據獨立性和易擴展性,而且可爲各類用戶共享。linux

  2.數據庫分類正則表達式

  2.1關係數據庫:Mysql,Oracle,sql server,db2,sqliteredis

  2.2非關係數據庫:redis ,mongodbsql

  3。數據庫系統mongodb

  數據庫系統DBS(Data Base System)一般由軟件、數據庫和數據管理員組成。其軟件主要包括操做系統、各類宿主語言、實用程序以及數據庫管理系統。數據庫由數據庫管理系通通一管理,數據的插入、修改和檢索均要經過數據庫管理系統進行。數據管理員負責建立、監控和維護整個數據庫,使數據能被任何有權使用的人有效使用。數據庫

2、mysql

  1.mysql的管理

  1.1安裝服務器

  linux:session

--yum -y install mariadb mariadb-server
OR
--yum -y install mysql mysql-server

  windouws:app

--http://dev.mysql.com/downloads/mysql/ 

  1.2:啓動

--service mysqld start  #開啓
--chkconfig mysqld on   #設置開機自啓
OR
--systemctl start mariadb
--systemctl enable mariadb

  1.3:查看

-- ps aux |grep mysqld    #查看進程
-- netstat -an |grep 3306 #查看端口

  1.4:設置密碼

-- mysqladmin -uroot password '123'   #設置初始密碼,初始密碼爲空所以-p選項沒有用
-- mysqladmin -u root -p123 password '1234' #修改root用戶密碼

  1.5:登陸

-- 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

  2.mysql的經常使用命令

-- 
-- 啓動mysql服務與中止mysql服務命令:
-- 
-- net start mysql
-- net stop  mysql
-- 
-- 登錄與退出命令:
-- 
--    mysql -h 服務器IP -P 端口號 -u  用戶名 -p 密碼 --prompt 命令提示符  --delimiter 指定分隔符
--    mysql -h 127.0.0.1 -P 3306 -uroot -p123
--    quit------exit----\q;
-- 
-- \s;   ------my.ini文件:[mysql] default-character-set=gbk [mysqld] character-set-server=gbk
-- 
-- prompt 命令提示符(\D:當前日期 \d:當前數據庫  \u:當前用戶)
-- 
-- \T(開始日誌) \t(結束日誌)
-- 
-- show warnings;
-- 
-- help() ? \h
-- 
-- \G;
-- 
-- select now();
-- select version();
-- select user;
-- 
-- \c 取消命令
-- 
-- delimiter 指定分隔符
 

  3.忘記密碼怎麼辦?

  方法1:啓動mysql時,跳過受權表

 
[root@controller ~]# service mysqld stop
[root@controller ~]# mysqld_safe --skip-grant-table &
[root@controller ~]# mysql
mysql> select user,host,password from mysql.user;
+----------+-----------------------+-------------------------------------------+
| user     | host                  | password                                  |
+----------+-----------------------+-------------------------------------------+
| root     | localhost             | *A4B6157319038724E3560894F7F932C8886EBFCF |
| root     | localhost.localdomain |                                           |
| root     | 127.0.0.1             |                                           |
| root     | ::1                   |                                           |
|          | localhost             |                                           |
|          | localhost.localdomain |                                           |
| root     | %                     | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
+----------+-----------------------+-------------------------------------------+
mysql> update mysql.user set password=password("123") where user="root" and host="localhost";
mysql> flush privileges;
mysql> exit
[root@controller ~]# service mysqld restart
[root@controller ~]# mysql -uroot -p123
 

  方法2:刪庫

刪除與權限相關的庫mysql,全部的受權信息都丟失,主要用於測試數據庫或者剛剛建庫不久沒有受權數據的狀況(從刪庫到跑路)
[root@controller ~]# rm -rf /var/lib/mysql/mysql
[root@controller ~]# service mysqld restart
[root@controller ~]# mysql

  4.sql:結構化語句規範:

  4.1:不區分大小寫(命令建議大寫)

  4.2:以分號做爲結束符號

  4.3:-- 單行註釋,/*多行註釋*/

  5.mysql數據類型

  MySQL支持多種類型,大體能夠分爲三類:數值、日期/時間和字符串(字符)類型。

  5.1:數值類型

  下面的表顯示了須要的每一個整數類型的存儲和範圍。

  

  5.2:日期和時間類型

  表示時間值的日期和時間類型爲DATETIME、DATE、TIMESTAMP、TIME和TEAR。

  每一個時間類型有一個有效值範圍和一個‘零’值,當指定不合法的mysql不能表示的值時使用‘零’值。

  

  5.3:字符串類型

  字符串類型指CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM和SET。該節描述了這些類型如何工做以及如何在查詢中使用這些類型。

  

  CHAR和VARCHAR類型相似,但它們保存和檢索的方式不一樣。它們的最大長度和是否尾部空格被保留等方面也不一樣。在存儲或檢索過程當中不進行大小寫轉換。

  BINARY和VARBINARY類相似於CHAR和VARCHAR,不一樣的是它們包含二進制字符串而不要非二進制字符串。也就是說,它們包含字節字符串而不是字符字符串。

  BLOB是一個二進制大對象,能夠容納可變數量的數據。有4種BLOB類型:TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB。它們只是可容納值的最大長度不一樣。

  有4種TEXT類型:TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT。這些對應4種BLOB類型,有相同的最大長度和存儲需求。

  6.數據庫的操做

  6.1:SHOW DATABASES;  --查看全部的數據庫

  6.2:CREATE DATABASE database_name  --建立數據庫

  6.3:SHOW CREATE DATABASE database_name  --查看建立數據庫信息

  6.4:DROP DATABASE database_naem  --刪除某個數據庫

  6.5:USE database_name  --使用某個數據庫

 
-- 1.建立數據庫(在磁盤上建立一個對應的文件夾)
    create database [if not exists] db_name [character set xxx] 
    
-- 2.查看數據庫
    show databases;查看全部數據庫
    show create database db_name; 查看數據庫的建立方式

-- 3.修改數據庫
    alter database db_name [character set xxx] 

-- 4.刪除數據庫
    drop database [if exists] db_name;
    
-- 5.使用數據庫
    切換數據庫 use db_name; -- 注意:進入到某個數據庫後沒辦法再退回以前狀態,但能夠經過use進行切換
    查看當前使用的數據庫 select database();

  7.數據表的操做

  7.1:建立一個表

  CREATE TABLE table_name(

      字段名  字段數據類型  [約束]  ,

      。。。。。

      字段名  字段數據類型  [約束] )

  7.2:修改表

  --增長列(字段)
  alter table tab_name add [column] 列名 類型[完整性約束條件][first|after 字段名];
  --修改一列類型
  alter table tab_name modify 列名 類型 [完整性約束條件][first|after 字段名];
  --修改列名
  alter table tab_name change [column] 列名 新列名 類型 [完整性約束條件][first|after 字段名];

  --刪除一列
  alter table tab_name drop [column] 列名;
  --修改表名
  rename table 表名 to 新表名;
  --修該表所用的字符集 
  alter table student character set utf8;

  7.3:查看錶

  DESC table_name  --查看錶詳細信息

  SHOW TABLES  --查看當前庫的全部列表

  SHOW CREATE TABLE table_name  --查看錶建立信息

  7.4:刪除表

  DROP TABLE table_name

  7.5:添加主鍵,刪除主鍵

  ALTER TABLE table_name ADD PRIMARY KEY(字段名稱,...);

  ALTER TABLE users DROP PRIMARY KEY;

 
-- 1.建立表(相似於一個excel表)

        create table tab_name(
            field1 type[完整性約束條件],
            field2 type,
            ...
            fieldn type
        )[character set xxx];

         -- 建立一個員工表employee

         create table employee(
            id int primary key auto_increment ,
            name varchar(20),
            gender bit default 1,   -- gender char(1)  default 1   -----    或者 TINYINT(1) 
            birthday date,
            entry_date date,
            job varchar(20),
            salary double(4,2) unsigned,
            resume text    -- 注意,這裏做爲最後一個字段不加逗號
          );


    /* 約束:
       primary key (非空且惟一)  :可以惟一區分出當前記錄的字段稱爲主鍵!
       unique
       not null
       auto_increment 主鍵字段必須是數字類型。
       外鍵約束 foreign key  */

-- 2.查看錶信息
    desc tab_name 查看錶結構
    show columns from tab_name  查看錶結構
    show tables 查看當前數據庫中的全部的表
    show create table tab_name    查看當前數據庫表建表語句 

-- 3.修改表結構
   -- (1)增長列(字段)
      alter table tab_name add [column] 列名 類型[完整性約束條件][first|after 字段名];
      alter table user add addr varchar(20) not null unique first/after username;
      #添加多個字段
      alter table users2 
            add addr varchar(20),
            add age  int first,
            add birth varchar(20) after name;

   -- (2)修改一列類型
      alter table tab_name modify 列名 類型 [完整性約束條件][first|after 字段名];
      alter table users2 modify age tinyint default 20;
      alter table users2 modify age int  after id;
   
   -- (3)修改列名
      alter table tab_name change [column] 列名 新列名 類型 [完整性約束條件][first|after 字段名];
      alter table users2 change age Age int default 28 first;

   -- (4)刪除一列
      alter table tab_name drop [column] 列名;
      -- 思考:刪除多列呢?刪一個填一個呢?
      alter table users2 
            add salary float(6,2) unsigned not null after name,
            drop addr;    

   -- (5)修改表名
      rename table 表名 to 新表名;
   -- (6)修該表所用的字符集    
      alter table student character set utf8;

-- 4.刪除表
    drop table tab_name;

---5 添加主鍵,刪除主鍵
    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
 

  建立文章表

 
create table article(
            id int primary key auto_increment ,
            title varchar(20),
            publish_date INT,
            click_num INT,
            is_top TINYINT(1),
            content TEXT
          );
 

  7.6:約束

  分類:

 
PRIMARY KEY (PK)    標識該字段爲該表的主鍵,能夠惟一的標識記錄
FOREIGN KEY (FK)    標識該字段爲該表的外鍵
NOT NULL    標識該字段不能爲空
UNIQUE KEY (UK)    標識該字段的值是惟一的
AUTO_INCREMENT    標識該字段的值自動增加(整數類型,並且爲主鍵)
DEFAULT    爲該字段設置默認值
UNSIGNED 無符號 ZEROFILL 使用0填充
 
複製代碼
#在建立完表後,修改自增字段的起始值
mysql> create table student(
    -> id int primary key auto_increment,
    -> name varchar(20),
    -> sex enum('male','female') default 'male'
    -> );

mysql> alter table student auto_increment=3;

mysql> show create table student;
.......
ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

mysql> insert into student(name) values('egon');
Query OK, 1 row affected (0.01 sec)

mysql> select * from student;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  3 | egon | male |
+----+------+------+
row in set (0.00 sec)

mysql> show create table student;
.......
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8


#也能夠建立表時指定auto_increment的初始值,注意初始值的設置爲表選項,應該放到括號外
create table student(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male'
)auto_increment=3;




#設置步長
sqlserver:自增步長
    基於表級別
    create table t1(
        id int。。。
    )engine=innodb,auto_increment=2 步長=2 default charset=utf8

mysql自增的步長:
    show session variables like 'auto_inc%';
    
    #基於會話級別
    set session auth_increment_increment=2 #修改會話級別的步長

    #基於全局級別的
    set global auth_increment_increment=2 #修改全局級別的步長(全部會話都生效)


#!!!注意了注意了注意了!!!
If the value of auto_increment_offset is greater than that of auto_increment_increment, the value of auto_increment_offset is ignored. 
翻譯:若是auto_increment_offset的值大於auto_increment_increment的值,則auto_increment_offset的值會被忽略 
好比:設置auto_increment_offset=3,auto_increment_increment=2




mysql> set global auto_increment_increment=5;
Query OK, 0 rows affected (0.00 sec)

mysql> set global auto_increment_offset=3;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'auto_incre%'; #須要退出從新登陸
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1     |
+--------------------------+-------+



create table student(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male'
);

mysql> insert into student(name) values('egon1'),('egon2'),('egon3');
mysql> select * from student;
+----+-------+------+
| id | name  | sex  |
+----+-------+------+
|  3 | egon1 | male |
|  8 | egon2 | male |
| 13 | egon3 | male |
+----+-------+------+

步長increment與起始偏移量offset:auto_increment_increment,auto_increment_offset
複製代碼

  單字段主鍵

  主鍵字段特色:非空且惟一

 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)
          );
複製代碼

  (1)一張表只能有一個主鍵

  (2)主鍵類型不必定非是整型

  7.7:複製表

 
複製表結構+記錄 (key不會複製: 主鍵、外鍵和索引)
mysql> create table new_service select * from service;

只複製表結構
mysql> select * from service where 1=2;        //條件爲假,查不到任何記錄
Empty set (0.00 sec)
mysql> create table new1_service select * from service where 1=2;  
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> create table t4 like employees;
 

  8.表記錄操做

  8.1:表記錄之增刪改

 
-- 1.增長一條記錄insert

      /*insert [into] tab_name (field1,filed2,.......) values (value1,value2,.......);*/


      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,'alex','1989-08-08',3000);

       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);

      -- set插入: insert [into] tab_name set 字段名=值

      insert into employee_new set id=12,name="alvin3";


-- 2.修改表記錄  update tab_name set field1=value1,field2=value2,......[where 語句]

    /*      UPDATE語法能夠用新值更新原有錶行中的各列。
            SET子句指示要修改哪些列和要給予哪些值。
            WHERE子句指定應更新哪些行。如沒有WHERE子句,則更新全部的行。*/


    update employee_new set birthday="1989-10-24" WHERE id=1;

    --- 將yuan的薪水在原有基礎上增長1000元。
    update employee_new set salary=salary+4000 where name='yuan';

-- 3.刪除表紀錄

     delete from tab_name [where ....]

        /*    若是不跟where語句則刪除整張表中的數據
            delete只能用來刪除一行記錄
            delete語句只能刪除表中的內容,不能刪除表自己,想要刪除表,用drop
            TRUNCATE TABLE也能夠刪除表中的全部數據,詞語句首先摧毀表,再新建表。此種方式刪除的數據不能在
            事務中恢復。*/

                -- 刪除表中名稱爲’alex’的記錄。
                delete from employee_new where name='alex';
                -- 刪除表中全部記錄。
                delete from employee_new;-- 注意auto_increment沒有被重置:alter table employee auto_increment=1;
                -- 使用truncate刪除表中記錄。
                truncate table emp_new;
 

  8.2:表記錄之查(單表查詢)

 
-- 查詢表達式

   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,"Amos",98,98,98), (2,"xialv",35,98,67), (3,"alex",59,59,62), (4,"wusir",88,89,82), (5,"alvin",88,98,67), (6,"sam",86,100,55); -- (1)select [distinct] *|field1,field2,...... from tab_name -- 其中from指定從哪張表篩選,*表示查找全部列,也能夠指定一個列 -- 代表確指定要查找的列,distinct用來剔除重複行。 -- 查詢表中全部學生的信息。 select * from ExamResult; -- 查詢表中全部學生的姓名和對應的英語成績。 select name,JS from ExamResult; -- 過濾表中重複數據。 select distinct JS ,name from ExamResult; -- (2)select 也可使用表達式,而且可使用: 字段 as 別名或者:字段 別名 -- 在全部學生分數上加10分特長分顯示。 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; -- what will happen?---->記得加逗號 -- (3)使用where子句,進行過濾查詢。 -- 查詢姓名爲XXX的學生成績 select * from ExamResult where name='yuan'; -- 查詢英語成績大於90分的同窗 select id,name,JS from ExamResult where JS>90; -- 查詢總分大於200分的全部同窗 select name,JS+Django+OpenStack as 總成績 from ExamResult where JS+Django+OpenStack>200 ; -- where字句中可使用: -- 比較運算符: > < >= <= <> != between 80 and 100 值在10到20之間 in(80,90,100) 值是10或20或30 like 'yuan%' /* pattern能夠是%或者_, 若是是%則表示任意多字符,此例如唐僧,唐國強 若是是_則表示一個字符唐_,只有唐僧符合。兩個_則表示兩個字符:__ */ -- 邏輯運算符 在多個條件直接可使用邏輯運算符 and or not -- 練習 -- 查詢JS分數在 70-100之間的同窗。 select name ,JS from ExamResult where JS between 80 and 100; -- 查詢Django分數爲75,76,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 Database is null; -- (4)Order by 指定排序的列,排序的列便可是表中的列名,也能夠是select 語句後指定的別名。 -- select *|field1,field2... from tab_name order by field [Asc|Desc] -- Asc 升序、Desc 降序,其中asc爲默認值 ORDER BY 子句應位於SELECT語句的結尾。 -- 練習: -- 對JS成績排序後輸出。 select * from ExamResult order by JS; -- 對總分排序按從高到低的順序輸出 select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(Database,0)) 總成績 from ExamResult order by 總成績 desc; -- 對姓李的學生成績排序輸出 select name ,(ifnull(JS,0)+ifnull(Django,0)+ifnull(OpenStack,0)) 總成績 from ExamResult where name like 'a%' order by 總成績 desc; -- (5)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; -- (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> 統計分組後的組記錄 -- (7) 重點: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; --- 成功 -- (8) limit SELECT * from ExamResult limit 1; SELECT * from ExamResult limit 2,5;--跳過前兩條顯示接下來的五條紀錄 SELECT * from ExamResult limit 2,2; --- (9) 使用正則表達式查詢 SELECT * FROM employee WHERE emp_name REGEXP '^yu'; SELECT * FROM employee WHERE emp_name REGEXP 'yun$'; SELECT * FROM employee WHERE emp_name REGEXP 'm{2}';
 

  9.外鍵約束

  9.1:建立外鍵

 
---  每個班主任會對應多個學生 , 而每一個學生只能對應一個班主任

----主表

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,     --切記:做爲外鍵必定要和關聯主鍵的數據類型保持一致
       -- [ADD CONSTRAINT charger_fk_stu]FOREIGN KEY (charger_id) REFERENCES ClassCharger(id)

) 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;
 

  9.2:INNODB支持的ON語句

 
--外鍵約束對子表的含義:   若是在父表中找不到候選鍵,則不容許在子表上進行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


------Restrict方式 :拒絕對父表進行刪除更新操做(瞭解)

------No action方式 在mysql中同Restrict,若是子表中有匹配的記錄,則不容許對父表對應候選鍵
   -- 進行update/delete操做(瞭解)
 

  10.多表查詢

  10.1:準備表

 
-- 準備兩張表
-- 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)
 

  10.2:多表查詢之鏈接查詢

  1.笛卡爾積查詢

 
mysql> SELECT * FROM employee,department;

--        select employee.emp_id,employee.emp_name,employee.age,
--        department.dept_name from employee,department;

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

  2.內鏈接

 
-- 查詢兩張表中都有的關聯數據,至關於利用條件從笛卡爾積結果中篩選出了正確的結果。

  select * from employee,department where employee.dept_id = department.dept_id;
--select * from employee inner 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 | 人事部    |
      +--------+----------+------+---------+---------+-----------+
 

  3.外鏈接

 
--(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會去掉相同的紀錄
 

  10.3:多表查詢之複合條件鏈接查詢

 
-- 查詢員工年齡大於等於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;
 

  10.3:多表查詢之子查詢

 
-- 查詢員工年齡大於等於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;
 

 

複製代碼
數據導入:

/*
 Navicat Premium Data Transfer

 Source Server         : localhost
 Source Server Type    : MySQL
 Source Server Version : 50624
 Source Host           : localhost
 Source Database       : sqlexam

 Target Server Type    : MySQL
 Target Server Version : 50624
 File Encoding         : utf-8

 Date: 10/21/2016 06:46:46 AM
*/

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `class`
-- ----------------------------
DROP TABLE IF EXISTS `class`;
CREATE TABLE `class` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `caption` varchar(32) NOT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `class`
-- ----------------------------
BEGIN;
INSERT INTO `class` VALUES ('1', '三年二班'), ('2', '三年三班'), ('3', '一年二班'), ('4', '二年九班');
COMMIT;

-- ----------------------------
--  Table structure for `course`
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `cname` varchar(32) NOT NULL,
  `teacher_id` int(11) NOT NULL,
  PRIMARY KEY (`cid`),
  KEY `fk_course_teacher` (`teacher_id`),
  CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `course`
-- ----------------------------
BEGIN;
INSERT INTO `course` VALUES ('1', '生物', '1'), ('2', '物理', '2'), ('3', '體育', '3'), ('4', '美術', '2');
COMMIT;

-- ----------------------------
--  Table structure for `score`
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `student_id` int(11) NOT NULL,
  `course_id` int(11) NOT NULL,
  `num` int(11) NOT NULL,
  PRIMARY KEY (`sid`),
  KEY `fk_score_student` (`student_id`),
  KEY `fk_score_course` (`course_id`),
  CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`),
  CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `score`
-- ----------------------------
BEGIN;
INSERT INTO `score` VALUES ('1', '1', '1', '10'), ('2', '1', '2', '9'), ('5', '1', '4', '66'), ('6', '2', '1', '8'), ('8', '2', '3', '68'), ('9', '2', '4', '99'), ('10', '3', '1', '77'), ('11', '3', '2', '66'), ('12', '3', '3', '87'), ('13', '3', '4', '99'), ('14', '4', '1', '79'), ('15', '4', '2', '11'), ('16', '4', '3', '67'), ('17', '4', '4', '100'), ('18', '5', '1', '79'), ('19', '5', '2', '11'), ('20', '5', '3', '67'), ('21', '5', '4', '100'), ('22', '6', '1', '9'), ('23', '6', '2', '100'), ('24', '6', '3', '67'), ('25', '6', '4', '100'), ('26', '7', '1', '9'), ('27', '7', '2', '100'), ('28', '7', '3', '67'), ('29', '7', '4', '88'), ('30', '8', '1', '9'), ('31', '8', '2', '100'), ('32', '8', '3', '67'), ('33', '8', '4', '88'), ('34', '9', '1', '91'), ('35', '9', '2', '88'), ('36', '9', '3', '67'), ('37', '9', '4', '22'), ('38', '10', '1', '90'), ('39', '10', '2', '77'), ('40', '10', '3', '43'), ('41', '10', '4', '87'), ('42', '11', '1', '90'), ('43', '11', '2', '77'), ('44', '11', '3', '43'), ('45', '11', '4', '87'), ('46', '12', '1', '90'), ('47', '12', '2', '77'), ('48', '12', '3', '43'), ('49', '12', '4', '87'), ('52', '13', '3', '87');
COMMIT;

-- ----------------------------
--  Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `gender` char(1) NOT NULL,
  `class_id` int(11) NOT NULL,
  `sname` varchar(32) NOT NULL,
  PRIMARY KEY (`sid`),
  KEY `fk_class` (`class_id`),
  CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `student`
-- ----------------------------
BEGIN;
INSERT INTO `student` VALUES ('1', '男', '1', '理解'), ('2', '女', '1', '鋼蛋'), ('3', '男', '1', '張三'), ('4', '男', '1', '張一'), ('5', '女', '1', '張二'), ('6', '男', '1', '張四'), ('7', '女', '2', '鐵錘'), ('8', '男', '2', '李三'), ('9', '男', '2', '李一'), ('10', '女', '2', '李二'), ('11', '男', '2', '李四'), ('12', '女', '3', '如花'), ('13', '男', '3', '劉三'), ('14', '男', '3', '劉一'), ('15', '女', '3', '劉二'), ('16', '男', '3', '劉四');
COMMIT;

-- ----------------------------
--  Table structure for `teacher`
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `tid` int(11) NOT NULL AUTO_INCREMENT,
  `tname` varchar(32) NOT NULL,
  PRIMARY KEY (`tid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
--  Records of `teacher`
-- ----------------------------
BEGIN;
INSERT INTO `teacher` VALUES ('1', '張磊老師'), ('2', '李平老師'), ('3', '劉海燕老師'), ('4', '朱雲海老師'), ('5', '李傑老師');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;
複製代碼
複製代碼
--一、將全部的課程的名稱以及對應的任課老師姓名打印出來,以下:
SELECT cname,tname FROM course INNER JOIN teacher WHERE course.teacher_id=teacher.tid;
--二、查詢學生表中男女生各有多少人? 以下:
SELECT gender,COUNT(gender) 人數 FROM student GROUP BY gender;
--三、查詢物理成績等於100的學生的姓名?以下:
SELECT sid,sname FROM student WHERE sid in (SELECT student_id FROM score WHERE course_id=2 and num=100);
--四、查詢平均成績大於八十分的同窗的姓名和平均成績,以下:
SELECT sname,平均成績 from (SELECT sid,sname from student) s INNER JOIN
(SELECT student_id,avg(num) 平均成績 from score GROUP BY student_id HAVING avg(num)>80) c
ON sid=student_id;
--五、查詢全部學生的學號,姓名,選課數,總成績
SELECT s.sid,s.sname,x.課程數,x.總成績 FROM (SELECT sid,sname FROM student) s INNER JOIN
(SELECT student_id,COUNT(course_id) 課程數,SUM(num) 總成績 from score GROUP BY student_id) x
ON sid=student_id;
--六、查詢姓李老師的個數
SELECT COUNT(tid) FROM teacher WHERE tname like '李%';
--七、查詢沒有報李平老師課的學生姓名
SELECT DISTINCT sname FROM student WHERE sid not in (SELECT DISTINCT student_id FROM score
WHERE course_id in (SELECT cid from course WHERE teacher_id=2));
--八、查詢物理課程比生物課程高的學生的學號
SELECT sw.student_id from (SELECT student_id,num from score WHERE course_id=(SELECT cid FROM course WHERE cname='物理')) wl INNER JOIN
( SELECT student_id,num from score WHERE course_id=(SELECT cid FROM course WHERE cname='生物')) sw
ON wl.num>sw.num and wl.student_id=sw.student_id;
--九、查詢沒有同時選修物理課程和體育課程的學生姓名
SELECT sname FROM student WHERE sid NOT in
(SELECT wl.student_id FROM (SELECT student_id,course_id from score WHERE course_id=(SELECT cid FROM course WHERE cname='物理')) wl INNER JOIN
(SELECT student_id,course_id from score WHERE course_id=(SELECT cid FROM course WHERE cname='體育')) ty
ON wl.student_id=ty.student_id);
--十、查詢掛科超過兩門(包括兩門)的學生姓名和班級
SELECT sname,caption FROM class INNER JOIN
(SELECT sname,class_id from student INNER JOIN (SELECT student_id,COUNT(student_id) 掛科次數 FROM score
WHERE num<60 GROUP BY student_id) gk ON sid=student_id and 掛科次數>1) s
ON cid=class_id;
--11 、查詢選修了全部課程的學生姓名
--方法一:
SELECT sname FROM student WHERE sid in (SELECT c.student_id FROM
(SELECT a.student_id FROM (SELECT * from score WHERE course_id=1) a
INNER JOIN (SELECT * from score WHERE course_id=2) b
ON a.student_id=b.student_id) c INNER JOIN
(SELECT a.student_id FROM (SELECT * from score WHERE course_id=2) a
INNER JOIN (SELECT * from score WHERE course_id=3) b
ON a.student_id=b.student_id) d
ON c.student_id=d.student_id);
--方法二:
SELECT sname FROM student WHERE sid in
(SELECT student_id FROM score GROUP BY student_id HAVING COUNT(course_id)=(SELECT COUNT(cid) FROM course));
--十二、查詢李平老師教的課程的全部成績記錄
 SELECT sid,sname,cname,num FROM course INNER JOIN (SELECT student.sid,sname,course_id,num FROM student
 INNER JOIN (SELECT * FROM score WHERE course_id in
(SELECT cid FROM course WHERE teacher_id=(SELECT tid FROM teacher WHERE tid=2))) a
ON student.sid=a.student_id) a WHERE cid=a.course_id;
--1三、查詢所有學生都選修了的課程號和課程名:沒有
SELECT * from (SELECT course_id,COUNT(student_id) 報名人數 FROM score GROUP BY course_id) a INNER JOIN
(SELECT COUNT(sid) 學生總數 FROM student) b
WHERE 報名人數=學生總數;
--1四、查詢每門課程被選修的次數
SELECT cname,選修次數 FROM course
INNER JOIN (SELECT course_id,COUNT(student_id) 選修次數
FROM score GROUP BY course_id) a
WHERE cid=course_id
--1五、查詢之選修了一門課程的學生姓名和學號
SELECT sname,sid FROM student
INNER JOIN (SELECT student_id FROM score GROUP BY student_id
HAVING COUNT(course_id)=1) a
WHERE sid=student_id
--1六、查詢全部學生考出的成績並按從高到低排序(成績去重)
SELECT DISTINCT num FROM score ORDER BY num DESC
--1七、查詢平均成績大於85的學生姓名和平均成績
SELECT sname,平均成績 from (SELECT sid,sname from student) s INNER JOIN
(SELECT student_id,avg(num) 平均成績 from score GROUP BY student_id HAVING avg(num)>85) c
ON sid=student_id;
--1八、查詢生物成績不及格的學生姓名和對應生物分數
SELECT sname,num FROM student INNER JOIN (SELECT student_id,num FROM score WHERE
course_id=(SELECT cid FROM course WHERE cname='生物') AND num<60) a
ON sid=student_id
--1九、查詢在全部選修了李平老師課程的學生中,這些課程(李平老師的課程,不是全部課程)平均成績最高的學生姓名
SELECT sname FROM student INNER JOIN (SELECT student_id,AVG(num) FROM score WHERE course_id IN (SELECT cid FROM course WHERE
teacher_id=(SELECT tid FROM teacher WHERE tname='李平老師'))
GROUP BY student_id ORDER BY AVG(num) DESC LIMIT 1) a
WHERE sid=student_id
相關文章
相關標籤/搜索