1. 程式人生 > >sql語句,單表和多表

sql語句,單表和多表

案例1-單表的curd
需求:
    對一張表中的資料進行增刪改查操作
    C:create 建立
    U:update 修改
    R:read     讀|檢索 查詢
    D:delete 刪除
技術分析:
    資料庫
    sql
/////////////////////////////////
資料庫:
    本質上就是一個檔案系統.通過標準的sql對資料進行curd操作
安裝 資料庫管理系統:
    資料庫管理系統大白話就是一個軟體
常見的關係型資料庫:
    關係型資料庫:
        存放實體與實體之間的關係的資料庫(就是二維表)
        實體:
            使用者     訂單    商品
        關係:
            使用者擁有訂單
            訂單包含商品
    非關係型資料庫:存放的是物件(redis) NO-sql(not only sql)
    
    軟體名        廠商        特點
    mysql        oracle        開源的資料庫
    oracle        oracle        大型的收費的資料庫
    DB2            IBM            大型的收費的資料庫
    sqlserver    微軟        中大型的收費的資料庫
    sybase        sybase(powerdesigner)

安裝了資料庫管理系統的計算機稱之為資料庫伺服器
    伺服器:給別人提供提供伺服器(軟體伺服器)
我們可以通過標準的sql在伺服器建立資料庫(database)
有了資料庫之後,就可以在資料庫上建立表了
有了表之後,就可以在裡面存放資料了.
SQL:
    結構化查詢語句
    作用:
        管理資料庫.
sql的分類:
    DDL:資料定義語言
        操作物件:資料庫和表
        關鍵詞:create alter drop
    DML:資料操作語言
        操作物件:記錄
    DQL:資料查詢語言(非官方)
    DCL:資料控制語言
        操作物件:使用者 事務 許可權
/////////////////////////////
登入資料庫:
    mysql -uroot  -p密碼
DDL:資料定義語言
        操作物件:資料庫和表
        關鍵詞:create alter drop    
    操作資料庫:
        建立:
            格式:
                create database 資料庫名稱;
        刪除:
            格式:
                drop database 資料庫名稱;
        常用的命令:
            檢視所有的資料庫: show databases;
    操作表:
        建立表
            格式:
                create table 表名(欄位描述,欄位描述);
                欄位描述:
                    欄位名稱 欄位型別 [約束]
                例如:
                    create table user(
                        id int primary key auto_increment,
                        username varchar(20)
                    );
                    
                    create table user1(
                        id int primary key auto_increment,
                        username varchar(20)
                    );
        修改表
            格式:
                alter table 表名 ....
            修改表名:
                alter table 舊錶名 rename to 新表名;
                例如:
                    alter table user1 rename to user10;
            新增欄位:
                alter table 表名 add [column] 欄位描述;
                例如:
                    alter table user add password varchar(20);
            修改欄位名:
                alter table 表名 change 欄位名稱 新欄位描述;
                例如:
                    alter table user change password pwd varchar(20);
            修改欄位描述:
                alter table 表名 modify 欄位名稱 欄位型別 [約束];
                例如:
                    alter table user modify pwd int;
            刪除欄位:
                alter table 表名 drop 欄位名;
                例如:
                    alter table user drop pwd;
            
        刪除表:
            格式:
                drop table 表名;
                
        常用命令:
            切換或者進入資料庫: use 資料庫名稱;
            檢視當前資料庫下所有表: show tables;
            查看錶結構:desc 表名;
            檢視建表語句:show create table 表名;
/////////////////////////////////////////////////
DML:資料操作語言
    操作物件:記錄(行)
    關鍵詞:insert update delete
    插入:
        格式1:
            insert into 表名 values(欄位值1,欄位值2...,欄位值n);
            注意:
                預設插入全部欄位,
                必須保證values後面的內容的型別和順序和表結構中的一致
                若欄位型別為數字,可以省略引號
            例如:
                insert into user values(1,'tom');
                insert into user values('2','tom');
                insert into user values('3');-- 錯誤的  
        
        格式2:
            insert into 表名(欄位名,欄位名1...) values(欄位值,欄位值1...);
            注意:
                插入指定的欄位
                必須保證values後面的內容的型別和順序和表名後面的欄位的型別和順序保持一致.
            例如:
                insert into user (username,id) values('jack',4);
                insert into user (username) values('jack',5);-- 錯誤的
            
    修改:
        格式:
            update 表名 set 欄位名=欄位值,欄位名1=欄位值1... [where 條件];
        例如:
            update user set username='jerry' where username='jack';
    刪除:
        格式:
            delete from 表名 [where 條件];
        例如:
            delete from user where id = '2';
///////////////////////////////////
DQL:資料查詢語言
        關鍵詞:select
    格式:
        select ... from 表名 where 條件 group by 分組欄位 having 條件 order by 排序欄位 ase|desc
    
    初始化環境:
        -- 建立商品表
        create table products(
            pid int primary key auto_increment,
            pname varchar(20),
            price double,
            pnum int,
            cno int,
            pdate timestamp
        );

        insert into products values (null,'泰國大榴蓮',98,12,1,null);
        insert into products values (null,'新疆大棗',38,123,1,null);
        insert into products values (null,'新疆切糕',68,50,2,null);
        insert into products values (null,'十三香',10,200,3,null);
        insert into products values (null,'老乾媽',20,180,3,null);
        insert into products values (null,'豌豆黃',20,120,2,null);
    練習:
        簡單查詢:
        練習:
        1.查詢所有的商品
            select * from products;
        2.查詢商品名和商品價格.
            -- 檢視指定的欄位 
            -- 格式: select 欄位名1,欄位名2 from 表名
            select pname,price from products;
        3.查詢所有商品都有那些價格.
            -- 去重操作 distinct
            -- 格式: select distinct 欄位名,欄位名2 from 表名
            select price from products;
            select distinct price from products;
        4.將所有商品的價格+10元進行顯示.(別名)
            -- 可以在查詢的結果之上進行運算,不影響資料庫中的值
            -- 給列起別名 格式: 欄位名 [as] 別名
            select price+10 from products;
            select price+10 新價格 from products;
            select price+10 '新價格' from products;
            select price+10 新 價 格 from products;-- 錯誤
            select price+10 '新 價 格' from products;
            select price+10 `新 價 格` from products;


        條件查詢:
        練習:
        1.查詢商品名稱為十三香的商品所有資訊:
            select * from products where pname = '十三香';
        2.查詢商品價格>60元的所有的商品資訊:
            select * from products where price>60;
        3.查詢商品名稱中包含”新”的商品
            -- 模糊匹配 
            --    格式: 欄位名 like "匹配規則";
            --        匹配內容 %
                            "龍"    值為龍
                            "%龍"    值以"龍"結尾
                            "龍%"    值以"龍"開頭
                            "%龍%"     值包含"龍"
            --        匹配個數 "__" 佔兩個位置
            
            select * from products where pname like "%新%";
        4.查詢價格為38,68,98的商品
            select * from products where price = 38 or price = 68 or price=98;
            select * from products where price in(38,68,98);
            
            where後的條件寫法:
                * > ,<,=,>=,<=,<>,!=
                * like 使用佔位符 _ 和 %  _代表一個字元 %代表任意個字元. 
                    * select * from product where pname like '%新%';
                * in在某個範圍中獲得值.
                    * select * from product where pid in (2,5,8);
                * between 較小值 and 較大值
                    select * from products where price between 50 and 70;
    
        排序查詢:
        1.查詢所有的商品,按價格進行排序.(asc-升序,desc-降序)
            select * from products order by price desc;
        2.查詢名稱有新的商品的資訊並且按價格降序排序.
            select * from products where pname like '%新%' order by price  desc;


        聚合函式:
            對一列進行計算 返回值是一個,忽略null值
        * sum(),avg(),max(),min(),count();
        1.獲得所有商品的價格的總和:
            select sum(price) from products;
        2.獲得商品表中價格的平均數:
            select avg(price) from products;
            -- round(值,保留小數位)
            select round(avg(price),2) from products;
        3.獲得商品表中有多少條記錄:
            select count(*) from products;

        分組:使用group by
        1.根據cno欄位分組,分組後統計商品的個數.
            select cno,count(*) from products group by cno;
        2.根據cno分組,分組統計每組商品的總數量,並且總數量> 200;
            select cno,sum(pnum) from products  group by cno;
            select cno,sum(pnum) from products  group by cno having sum(pnum)>200;
            注意:
                where和having區別:
                    1.where 是對分組前的資料進行過濾 ;having 是對分組後的資料進行過濾 
                    2.where 後面不能使用聚合函式,having可以
/////////////////////////////////
資料型別:(瞭解)
java            mysql        
byte            tinyint            
short            smallint
int                int(★)
long            bigint
char/String        varchar(★)|char
                    varchar:可變長度 mysql的方言  varchar(20):  存放abc 只會佔用三個
                    char:固定長度 char(20) 存放abc 佔用20個
boolean            tinyint|int 代替
float|double    float|double
                    注意:
                        double(5,2):該小數長度為5個,小數佔2個  最大值:999.99


java.sql.Date        date 日期
java.sql.Time        time 時間
java.sql.Timestamp    timestamp(★) 時間戳 若給定值為null,資料庫會把當前的系統時間存放到資料庫中
                    datetime(★) 日期+時間
                    
java.sql.Clob(長文字)    mysql的方言(text)
java.sql.Blob(二進位制)    blob
//////////////////////////////////
約束:
    作用:
        為了保證資料的有效性和完整性
    mysql中常用的約束:主鍵約束(primary key)  唯一約束(unique) 非空約束(not null) 外來鍵約束(foreign key)
    主鍵約束:被修飾過的欄位唯一非空
        注意:一張表只能有一個主鍵,這個主鍵可以包含多個欄位
        方式1:建表的同時新增約束 格式: 欄位名稱 欄位型別 primary key
        方式2:建表的同時在約束區域新增約束 
            所有的欄位宣告完成之後,就是約束區域了
            格式: primary key(欄位1,欄位2)
            
            create table pk01(
                id int,
                username varchar(20),
                primary key (id)
            );
            
            insert into pk01 values(1,'tom');-- 成功
            insert into pk01 values(1,'tom');-- 失敗 Duplicate entry '1' for key 'PRIMARY'
            insert into pk01 values(null,'tom');-- 失敗  Column 'id' cannot be null
            
            create table pk01(
                id int primary key,
                username varchar(20),
                primary key (id)
            );-- 錯誤的 一張表只能有一個主鍵
            
        方式3:建表之後,通過修改表結構新增約束
            create table pk02(
                id int,
                username varchar(20)
            );
            
            alter table pk02 add primary key(欄位名1,欄位名2..);
            alter table pk02 add primary key(id,username);
            
            insert into pk02 values(1,'tom');-- 成功
            insert into pk02 values(1,'tomcat');-- 成功
            insert into pk02 values(1,'tomcat');-- 失敗
        
    唯一約束:(瞭解)
        被修飾過的欄位唯一,對null不起作用
        方式1:建表的同時新增約束 格式: 欄位名稱 欄位型別 unique
            create table un(
                id int unique,
                username varchar(20) unique
            );
            
            insert into un value(10,'tom');-- 成功
            insert into un value(10,'jack');-- 錯誤 Duplicate entry '10' for key 'id'
            insert into un value(null,'jack');-- 成功
            insert into un value(null,'rose');-- 成功
            
        方式2:建表的同時在約束區域新增約束 
            所有的欄位宣告完成之後,就是約束區域了
            unique(欄位1,欄位值2...)
        方式3:建表之後,通過修改表結構新增約束
            alter table 表名 add unique(欄位1,欄位2);-- 新增的聯合唯一
            alter table 表名 add unique(欄位1);-- 給一個新增唯一
            alter table 表名 add unique(欄位2);-- 給另一個新增唯一
            
            ////////////////
                create table un01(
                    id int,
                    username varchar(20)
                ); 
                alter table un01 add unique(id,username);
                insert into un01 values(1,'tom');-- 成功
                insert into un01 values(1,'jack');-- 成功
                insert into un01 values(1,'tom');-- 失敗  Duplicate entry '1-tom' for key 'id'
            /////////////////////
    非空約束(瞭解)
        特點:被修飾過的欄位非空
        方式:
            create table nn(
                id int not null,
                username varchar(20) not null
            );
            
            insert into nn values(null,'tom');--  錯誤的 Column 'id' cannot be null
///////////////////////////////
truncate 清空表 ★
    格式:
        truncate 表名; 幹掉表,重新建立一張空表
    和delete from 區別:
        delete屬於DML語句  truncate屬於DDL語句
        delete逐條刪除    truncate幹掉表,重新建立一張空表
        
auto_increment 自增
    要求:
        1.被修飾的欄位型別支援自增. 一般int
        2.被修飾的欄位必須是一個key 一般是primary key
    
    create table ai01(
        id varchar(10) auto_increment
    );-- 錯誤 Incorrect column specifier for column 'id'
    
    create table ai01(
        id int auto_increment
    );-- 錯誤 Incorrect table definition; there can be only one auto column and it must be defined as a key
///////////////////////////////
案例2-建立多表,可以描述出表於表之間的關係
需求:
    把網上商城裡面用的實體建立成表,並且將他們之間建立關係.
技術分析:
    sql

/////////////////////////////////
網上商城的實體:
    使用者 訂單 商品 分類
常見關係:
    一對多. 使用者和訂單  分類和商品
    多對多. 訂單和商品    學生和課程
    一對一. 丈夫和妻子    
ER圖可以描述實體於實體之間的關係
    實體用矩形表示
    屬性用橢圓表示
    關係用菱形表示
////////////////////
一對多:
    使用者和訂單    
    -- 建立使用者表
    create  table user(
        id int primary key auto_increment,
        username varchar(20)
    );
    
    -- 建立訂單表
    create  table orders(
        id int primary key auto_increment,
        totalprice double,
        user_id int
    );
    
    為了保證資料的有效性和完整性,新增約束(外來鍵約束).
        在多表的一方新增外來鍵約束
            格式:
                alter table 多表名稱 add foreign key(外來鍵名稱) references 一表名稱(主鍵);
            例如:
                alter table orders add foreign key(user_id) references user(id);
    添加了外來鍵約束之後有如下特點:★
        1.主表中不能刪除從表中已引用的資料
        2.從表中不能新增主表中不存在的資料
    開發中處理一對多:★
        在多表中新增一個外來鍵,名稱一般為主表的名稱_id,欄位型別一般和主表的主鍵的型別保持一致,
        為了保證資料的有效性和完整性,在多表的外來鍵上新增外來鍵約束即可.
////////////////////////
多對多
    例子:商品和訂單
        -- 建立商品表
    create table product(
        id int primary key auto_increment,
        name varchar(20),
        price double
    );

    -- 建立中間表
    create table orderitem(
        oid int,
        pid int
    );
        
    -- 新增外來鍵約束
    alter table orderitem add foreign key(oid) references orders(id);
    alter table orderitem add foreign key(pid) references product(id);
    
    開發中處理多對多:★
        引入一張中間表,存放兩張表的主鍵,一般會將這兩個欄位設定為聯合主鍵,這樣就可以將多對多的關係拆分
        成兩個一對多了
        為了保證資料的有效性和完整性
            需要在中間表上新增兩個外來鍵約束即可.
///////////////////////////////////////////////////
案例3-多表查詢
技術分析:
    內連線
    外連線
    子查詢
/////////////////////////////
笛卡爾積:瞭解
    多張表無條件的聯合查詢.沒有任何意思
        select a.*,b.* from a,b;
        
內連線:★
    格式1:顯式的內連線
        select a.*,b.* from a [inner] join b on ab的連線條件
    格式2:隱式的內連線
        select a.*,b.* from a,b where ab的連線條件
外連線:★
    左外連線:★
        select a.*,b.* from a left [outer] join b on 連線條件;
        意思:
            先展示join左邊的(a)表的所有資料,根據條件關聯查詢 join右邊的表(b),符合條件則展示出來,不符合以null值展示.
    右外連線:
        select a.*,b.* from b right [outer] join a on 連線條件;
        意思:
            先展示jion右邊的表(a)表的所有資料,根據條件關聯查詢join左邊的表(b),符合條件則展示出來,不符合以null值展示.
子查詢:★
    一個查詢依賴另一個查詢.
    


練習:
    查詢使用者的訂單,沒有訂單的使用者不顯示
        隱式內連線:
            select user.*,orders.* from user ,orders where user.id=orders.user_id;
        顯示內連線
            select user.*,orders.* from user join orders on user.id=orders.user_id;
    查詢所有使用者的訂單詳情
        左外連線: user在左
            select user.*,orders.* from user left join orders on user.id=orders.user_id;
    查詢所有訂單的使用者詳情
        右外連線:orders 在右
            select orders.*,user.* from user right join orders on user.id=orders.user_id;
            
練習:
    檢視使用者為張三的訂單詳情
        1.先查詢張三的id
            select id from User where username = '張三';// 3
        2.select * from orders where user_id = ?;
        
        兩個合二為一
            select * from orders where user_id = (select id from User where username = '張三');
    查詢出訂單的價格大於300的所有使用者資訊。
        1.先查詢出訂單價格>300的使用者的id
            select user_id from orders where price >300;//(3,3,5,null)
        2.select * from user where id in(3,3,5,null);
        
        兩個合二為一:
            select * from user where id in(select user_id from orders where price >300);
    查詢訂單價格大於300的訂單資訊及相關使用者的資訊。
        內連線:
            select orders.*,user.* from orders,user where user.id=orders.user_id  and orders.price>300 ;
        
        子查詢:    是將一個查詢的結果作為一張臨時表        
            select user.*,tmp.* from user,(select * from orders where price>300) as tmp where user.id=tmp.user_id;
    
    給表起別名
        格式: 表 [as] 別名
        //////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////

    初始化資料:
    -- 使用者表(user) 
       create table `user` (                                  
              `id` int auto_increment primary key,                
              `username` varchar(50)  -- 使用者姓名                                                
            );

    -- 訂單表(orders)
       create table `orders` (                                                  
              `id` int  auto_increment primary key,                                  
              `price` double,                                           
              `user_id` int                                       
            );
    -- 給訂單表新增外來鍵約束
    alter table orders add constraint user_fk foreign key (user_id) references user(id); 

    -- 向user表中新增資料
            insert into user values(3,'張三');
            insert into user values(4,'李四');
            insert into user values(5,'王五');
            insert into user values(6,'趙六');

    -- 向orders 表中插入資料
            insert into orders values(1,1314,3);
            insert into orders values(2,1314,3);
            insert into orders values(3,15,4);
            insert into orders values(4,315,5);
            insert into orders values(5,1014,null);
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
    
    
    
    
    
    
///////////////////////////////////////////
上午回顧:
sql分類:
    DDL:
        物件:資料庫和表
        關鍵詞:create alter drop
        建立資料庫:create database day0601;
        刪除資料庫:drop database day0601;
        
        use day0601;
        
        建立表:
            create table user(
                id int primary key  auto_increment,
                username varchar(20)
            );
        
        修改表:
            alter table user rename to user10;
            alter table user add password varchar(20);
            alter table change password pwd varchar(20);
            alter table modify pwd int;
            alter table drop pwd;
        刪除表 
            drop table user;
    DML:
        操作物件:記錄
        關鍵詞:insert update delete
    
        插入:
            insert into user values(欄位值1...);
            insert into user(欄位,欄位2) values(欄位值,欄位值2);
        更新:
            update user set 欄位名=欄位值,欄位名1=欄位值1 where 條件
        刪除:
            delete from user where 條件
            
    DQL:
        select ... from user where 條件 group by 分組欄位 order by 排序欄位 asc|desc;
    DCL:
//////////////////////
多表的建立,關係的建立
常見的關係:
    一對多:
        在開發中,在多表的一方新增一個外來鍵,外來鍵的名稱一般為主表的名稱_id,欄位型別一般和主表的主鍵的型別保持一致.
        為了保證資料的有效性和完整性,
            在多表的一方新增外來鍵約束(不是必須的,也可以通過java程式來控制)
                格式:
                    alter table 多表名稱 add foreign key(外來鍵名稱) references 主表名稱(主鍵名稱)
                    
    多對多:
        在開發中,一般引入一箇中間表,在中間表中存放另外兩張表的主鍵.這樣就可以將多對多的關係拆分兩個一對多的關係
        為了保證資料的有效性和完整性,
            在中間表上新增兩個外來鍵約束(不是必須的,也可以通過java程式來控制)
        
        外來鍵約束的特點:
            1.主表中不能刪除從表中已引用的資料
            2.從表中不能新增主表中不存在的資料
            
    一對一:瞭解
        在開發中,例如:person idcard
            思路1:將兩個實體合二為一
            思路2:在一個表上將這個表的主鍵設定成外來鍵且新增外來鍵約束.
    
多表查詢:
    內連線:
        顯式的內連線
            select a.* ,b.* from a join b on 連線條件;
        隱式內連線
            select a.*,b.* from a,b where 連線條件;
    外連線
        左外連線:
            select a.*,b.* from a left join b on 連線條件.
            展示a表所有資料,根據條件關聯查詢b表,滿足條件展示,不滿足以null值展示
    子查詢
        給表起別名:
            表 [as] 別名
//////////////////////