Java學習日誌(三十一): 多表查詢,內連接,外連接

JavaEE學習日誌持續更新----> 必看!JavaEE學習路線(文章總彙)

用戶和角色的多對多關係

在這裏插入圖片描述
首先先創建一個新的數據庫

-- 創建數據庫day03
CREATE DATABASE day03;
-- 使用數據庫
USE day03;

建表原則:創建一張中間表,使用兩個主表的主鍵作爲外鍵

  • 主表:用戶表users 角色表roles
  • 中間表users_roles
-- 創建主表用戶表users 字段:用戶主鍵,用戶名,密碼
CREATE TABLE users(
  -- 用戶主鍵
  uid INT PRIMARY KEY AUTO_INCREMENT,
  -- 用戶名
  username VARCHAR(20),
  -- 密碼
  PASSWORD VARCHAR(20)

);
-- 用戶表添加數據
INSERT INTO users(username,PASSWORD) VALUES('羣演1','1234'),('羣演2','5678');

-- 創建主表角色表roles 字段:角色主鍵,角色名稱
CREATE TABLE roles(
  -- 角色主鍵
  rid INT PRIMARY KEY AUTO_INCREMENT,
  -- 角色名稱
  rname VARCHAR(20)
);

-- 角色表添加數據
INSERT INTO roles(rname) VALUES('皇上'),('皇后'),('太監'),('宮女');

-- 創建中間表 users_roles
CREATE TABLE users_roles(
  -- 用戶主鍵
  users_uid INT,
  -- 角色主鍵
  roles_rid INT,
  -- 添加外鍵約束
  FOREIGN KEY(users_uid) REFERENCES users(uid),
  FOREIGN KEY(roles_rid) REFERENCES roles(rid)
);

-- 中間表添加兩個主表都有的數據
INSERT INTO users_roles VALUES(1,1),(1,2),(1,3),(1,4),(2,2),(2,3),(2,4);

-- 中間表添加主表用戶表不存在的數據
-- Cannot add or update a child row
INSERT INTO users_roles VALUES(3,1);

-- 中間表添加主表角色表不存在的數據
-- Cannot add or update a child row
INSERT INTO users_roles VALUES(1,5);

-- 刪除主表角色表名稱爲太監的數據
-- Cannot delete or update a parent row
DELETE FROM roles WHERE rname='太監';

-- 先刪除中間表中使用了太監的數據,再刪除角色表中的數據,則可以刪除
DELETE FROM users_roles WHERE roles_rid=3;
DELETE FROM roles WHERE rname='太監';

多表查詢

多表查詢的方式

多表查詢:一次查詢兩張以上的表
一、交叉連接查詢:很少使用,有錯誤數據
格式:select* from 表A,表B;

二、內連接查詢:在交叉連接查詢的基礎上,使用外鍵約束作爲查詢條件

  • 隱式內連接:不使用關鍵字[inner]join on
    格式:select * from 表A,表B where 表A.主鍵=表B.外鍵;
  • 顯式內連接:使用關鍵字[inner]join on
    格式:select * from 表A [inner]join 表B on 表A.主鍵=表B.外鍵;

三、外連接查詢:在交叉連接查詢的基礎上,使用外鍵約束作爲查詢條件

  • 左外連接查詢:使用關鍵字left [outer] join on
    格式:select * from 表A left [outer] join 表B on 表A.主鍵=表B.外鍵;
    注意:
    - 左外連接查詢以左邊的表爲主:
    - 左邊有的數據,右邊沒有,使用空代替
    - 左邊沒有的數據,右邊也不能出現
  • 右外連接查詢:使用關鍵字right [outer] join on
    格式:select * from 表A right [outer] join 表B on 表A.主鍵=表B.外鍵;
    注意:
    - 右外連接查詢以右邊的表爲主:
    - 右邊有的數據,左邊沒有,使用空代替
    - 右邊沒有的數據,左邊也不能出現

四、子查詢(sql語句的嵌套查詢)

  • 一條sql語句的查詢結果,作爲另外一條sql語句的查詢條件
    格式:
    select * from 表B where 字段 = (select 字段 from 表A [where 條件])
  • 一條sql語句的查詢結果,作爲另一條sql語句的一張表(隱式內連接查詢)
    格式:
    select * from (select * from 表A [where 條件]),表B where 表A.主鍵=表B.外鍵;

準備數據

# 分類表
CREATE TABLE category (  
    cid VARCHAR(32) PRIMARY KEY,
    cname VARCHAR(50)
);
#商品表
CREATE TABLE products(
    pid VARCHAR(32) PRIMARY KEY,
    pname VARCHAR(50),  
    price INT,  
    flag VARCHAR(2), #是否上架標記爲:1表示上架、0表示下架  
    category_id VARCHAR(32),
    CONSTRAINT products_fk FOREIGN KEY (category_id) REFERENCES category (cid)
);
#分類
INSERT INTO category(cid,cname) VALUES('c001','家電');
INSERT INTO category(cid,cname) VALUES('c002','服飾');
INSERT INTO category(cid,cname) VALUES('c003','化妝品');
#商品
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p001','聯想',5000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p002','海爾',3000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p003','雷神',5000,'1','c001');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p004','JACKJONES',800,'1','c002');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p005','真維斯',200,'1','c002');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p006','花花公子',440,'1','c002');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p007','勁霸',2000,'1','c002');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p008','香奈兒',800,'1','c003');
INSERT INTO products(pid, pname,price,flag,category_id) VALUES('p009','相宜本草',200,'1','c003');

category表
在這裏插入圖片描述
products表
在這裏插入圖片描述
架構圖
在這裏插入圖片描述

交叉連接查詢

交叉連接查詢:很少使用,有錯誤數據
格式:select* from 表A,表B;

一次性查詢出分類表和商品表的所有數據

SELECT * FROM category,products;

查詢結果:兩個表所有數據的乘積(3*9=27)–>笛卡爾積
在這裏插入圖片描述

內連接查詢

內連接查詢:在交叉連接查詢的基礎上,使用外鍵約束作爲查詢條件

  • 隱式內連接:不使用關鍵字[inner]join on
    格式:select * from 表A,表B where 表A.主鍵=表B.外鍵;
  • 顯式內連接:使用關鍵字[inner]join on
    格式:select * from 表A [inner]join 表B on 表A.主鍵=表B.外鍵;

隱式內連接

SELECT * FROM category,products WHERE category.cid = products.category_id;

-- 使用給表起別名,簡化sql語句
SELECT * FROM category c,products p WHERE c.cid = p.category_id;

顯式內連接

SELECT * FROM category c INNER JOIN products p ON c.cid = p.category_id;

在這裏插入圖片描述

查詢哪些分類的商品已經上架

SELECT * FROM category c,products p WHERE c.cid = p.category_id AND p.flag = '1'

外連接查詢

外連接查詢:在交叉連接查詢的基礎上,使用外鍵約束作爲查詢條件

  • 左外連接查詢:使用關鍵字left [outer] join on
    格式:select * from 表A left [outer] join 表B on 表A.主鍵=表B.外鍵;
    注意:
    - 左外連接查詢以左邊的表爲主:
    - 左邊有的數據,右邊沒有,使用空代替
    - 左邊沒有的數據,右邊也不能出現
  • 右外連接查詢:使用關鍵字right [outer] join on
    格式:select * from 表A right [outer] join 表B on 表A.主鍵=表B.外鍵;
    注意:
    - 右外連接查詢以右邊的表爲主:
    - 右邊有的數據,左邊沒有,使用空代替
    - 右邊沒有的數據,左邊也不能出現
    在這裏插入圖片描述
    修改category表
    在這裏插入圖片描述
    左外連接
SELECT * FROM category c LEFT OUTER JOIN products p ON c.cid = p.category_id;

在這裏插入圖片描述
右外連接

SELECT * FROM category c RIGHT OUTER JOIN products p ON c.cid = p.category_id;

在這裏插入圖片描述
使用左外連接查詢,查詢每類商品的個數

SELECT cid,COUNT(p.category_id) FROM category c LEFT JOIN products p 
ON c.cid = p.category_id 
GROUP BY cid;

子查詢

  • 一條sql語句的查詢結果,作爲另外一條sql語句的查詢條件
    格式:
    select * from 表B where 字段 = (select 字段 from 表A [where 條件])
  • 一條sql語句的查詢結果,作爲另一條sql語句的一張表(隱式內連接查詢)
    格式:
    select * from (select * from 表A [where 條件]),表B where 表A.主鍵=表B.外鍵;

查詢商品表,只顯示化妝品的信息

-- 一條sql語句的查詢結果,作爲另外一條sql語句的查詢條件
SELECT * FROM products WHERE category_id = (SELECT cid FROM category WHERE cname = '化妝品')

在這裏插入圖片描述

-- 一條sql語句的查詢結果,作爲另一條sql語句的一張表(隱式內連接查詢)
SELECT * FROM products p, (SELECT * FROM category WHERE cname = '化妝品') c WHERE c.cid = p.category_id ;

在這裏插入圖片描述
注意:如果用子查詢,且查詢的條件中有in,則必須使用in來接收子查詢的查詢結果,否則會報錯
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章