MySQL 多表操作與復雜查詢:深入理解多表關系和高級查詢

大家好!今天我們要深入探討 MySQL 中兩個非常重要的主題——多表操作復雜查詢


一. 多表操作

什么是多表操作?

在實際應用中,數據通常分布在多個表中,需要通過多表操作來獲取完整信息。比如,一個學生表和一個課程表之間的關系,我們需要通過多表操作來查詢某個學生的選課情況。

核心內容:
  • 多表關系
  • 外鍵約束
  • 聯合查詢

1. 多表關系

一對一關系

一個表中的一條記錄對應另一個表中的一條記錄。例如,用戶表和個人信息表之間可以是一對一的關系。

-- 用戶表
CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100) NOT NULL UNIQUE
);-- 個人信息表
CREATE TABLE user_profiles(user_id INT PRIMARY KEY,address VARCHAR(255),phone VARCHAR(20),FOREIGN KEY (user_id) REFERENCES users(id)
);
一對多關系

一個表中的一條記錄對應另一個表中的多條記錄。例如,訂單表和用戶表之間可以是一對多的關系。

-- 用戶表
CREATE TABLE users(id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100) NOT NULL UNIQUE
);-- 訂單表
CREATE TABLE orders(id INT PRIMARY KEY AUTO_INCREMENT,order_number VARCHAR(50) NOT NULL,user_id INT,order_date DATE,FOREIGN KEY (user_id) REFERENCES users(id)
);
多對多關系

一個表中的多條記錄對應另一個表中的多條記錄。例如,學生表和課程表之間可以是多對多的關系。

-- 學生表
CREATE TABLE students(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL
);-- 課程表
CREATE TABLE courses(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL
);-- 學生選課表(中間表)
CREATE TABLE student_courses(student_id INT,course_id INT,score DECIMAL(5,2),PRIMARY KEY(student_id, course_id),FOREIGN KEY(student_id) REFERENCES students(id),FOREIGN KEY(course_id) REFERENCES courses(id)
);

注意:

  • 多對多關系需要通過中間表來實現。
  • 中間表包含兩個外鍵,分別引用兩個表的主鍵。

2. 外鍵約束

創建外鍵約束

外鍵約束用于建立表與表之間的關聯關系,確保數據的完整性和一致性。

-- 創建訂單表,包含訂單ID、訂單號、客戶ID、訂單日期字段
CREATE TABLE orders(id INT PRIMARY KEY AUTO_INCREMENT,order_number VARCHAR(50) NOT NULL,customer_id INT,order_date DATE,FOREIGN KEY (customer_id) REFERENCES customers(id)
);
驗證外鍵約束的作用
-- 插入有效員工數據
INSERT INTO employees VALUES(1, '張三', 1), (2, '李四', 2);-- 插入無效員工數據(dept_id不存在)
INSERT INTO employees VALUES(3, '王五', 3); -- 會報錯-- 刪除被引用的部門
DELETE FROM departments WHERE id = 1; -- 會報錯

注意:

  • 禁止插入無效的外鍵值。
  • 禁止刪除被引用的父表記錄。
  • 可以配置級聯操作(如?ON DELETE CASCADE)。

3. 聯合查詢

交叉連接(CROSS JOIN)

返回兩個表的笛卡爾積,即兩個表中所有行的組合。

-- 交叉連接
SELECT * FROM departments CROSS JOIN employees;-- 或者
SELECT * FROM departments, employees;
內連接(INNER JOIN)

返回兩個表中匹配條件的行。

-- 內連接
SELECT e.id, e.name, d.name AS dept_name, e.salary 
FROM employees e 
INNER JOIN departments d ON e.dept_id = d.id;
左外連接(LEFT JOIN)

返回左表中的所有行,以及右表中匹配條件的行。如果右表中沒有匹配的行,則返回 NULL

-- 左外連接
SELECT e.id, e.name, d.name AS dept_name, e.salary 
FROM employees e 
LEFT JOIN departments d ON e.dept_id = d.id;
右外連接(RIGHT JOIN)

返回右表中的所有行,以及左表中匹配條件的行。如果左表中沒有匹配的行,則返回 NULL

-- 右外連接
SELECT e.id, e.name, d.name AS dept_name, e.salary 
FROM employees e 
RIGHT JOIN departments d ON e.dept_id = d.id;

二. 復雜查詢

什么是復雜查詢?

復雜查詢是指通過子查詢、聚合函數、分組等手段進行的高級查詢操作。它可以幫助我們從大量數據中提取所需的信息。

核心內容:
  • 子查詢
  • 聚合函數
  • 分組查詢

1. 子查詢

基本子查詢

嵌套在其他 SQL 語句中的查詢。它可以返回單個值、多個值或表。

-- 標量子查詢:查詢工資高于平均工資的員工
SELECT * FROM employees WHERE salary > (SELECT AVG(salary) FROM employees
);-- 列子查詢:查詢技術部和市場部的員工
SELECT * FROM employees WHERE dept_id IN (SELECT id FROM departments WHERE name IN ('技術部', '市場部')
);
ALL 關鍵字

表示與子查詢返回的所有值進行比較。

-- 查詢工資高于所有市場部員工的員工
SELECT * FROM employees WHERE salary > ALL (SELECT salary FROM employees WHERE dept_id = (SELECT id FROM departments WHERE name = '市場部')
);
ANY/SOME 關鍵字

表示與子查詢返回的任意一個值進行比較。

-- 查詢工資高于市場部任意一個員工的員工
SELECT * FROM employees WHERE salary > ANY (SELECT salary FROM employees WHERE dept_id = (SELECT id FROM departments WHERE name = '市場部')
);
EXISTS 關鍵字

表示子查詢是否返回結果集。

-- 查詢有員工的部門
SELECT * FROM departments d WHERE EXISTS (SELECT * FROM employees e WHERE e.dept_id = d.id
);

2. 聚合函數

聚合函數用于統計、求和、平均值等操作。

-- 統計學生總數
SELECT COUNT(*) AS 學生總數 FROM students;-- 計算總成績
SELECT SUM(score) AS 總成績 FROM students;-- 最高分和最低分
SELECT MAX(score) AS 最高分, MIN(score) AS 最低分 FROM students;-- 按班級分組,統計每個班級的學生數量
SELECT class_id, COUNT(*) AS 學生數量 FROM students GROUP BY class_id;-- 按班級分組,計算每個班級的平均成績
SELECT class_id, AVG(score) AS 平均成績 FROM students GROUP BY class_id;-- 分組后篩選,只顯示學生數量大于2的班級
SELECT class_id, COUNT(*) AS 學生數量 
FROM students 
GROUP BY class_id 
HAVING COUNT(*) > 2;

3. 自關聯查詢

自關聯查詢是指表與自身進行連接查詢,通常用于處理層次結構數據。

-- 創建員工表,包含上級ID
CREATE TABLE employees(id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,manager_id INT
);-- 插入數據
INSERT INTO employees VALUES (1, '張三', NULL), (2, '李四', 1), (3, '王五', 1), (4, '趙六', 2);-- 自關聯查詢,查詢員工及其上級
SELECT e.name AS 員工, m.name AS 上級
FROM employees e 
LEFT JOIN employees m ON e.manager_id = m.id;

三. 總結與最佳實踐

總結

操作類型說明
一對一關系一個表中的一條記錄對應另一個表中的一條記錄
一對多關系一個表中的一條記錄對應另一個表中的多條記錄
多對多關系一個表中的多條記錄對應另一個表中的多條記錄,需通過中間表實現
外鍵約束建立表與表之間的關聯關系,確保數據的完整性和一致性
交叉連接返回兩個表的笛卡爾積
內連接返回兩個表中匹配條件的行
左外連接返回左表中的所有行,以及右表中匹配條件的行
右外連接返回右表中的所有行,以及左表中匹配條件的行
子查詢嵌套在其他 SQL 語句中的查詢
聚合函數用于統計、求和、平均值等操作
自關聯查詢表與自身進行連接查詢

最佳實踐

  • 合理使用多表關系:根據業務需求選擇合適的關系類型。
  • 靈活運用聯合查詢:根據需求選擇合適的連接方式。
  • 優化復雜查詢性能:避免不必要的復雜查詢,適當使用索引。

一句話總結:

多表操作幫助我們構建復雜的數據庫模型,而復雜查詢則是我們的“數據探索工具”,幫助我們在數據庫中高效地獲取所需信息。


結尾

通過這篇博客,我們詳細講解了 MySQL 中多表操作和復雜查詢的核心概念和使用方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96331.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96331.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96331.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java入門級教程7——eclipse新建Maven項目,創建和連接數據庫,創建數據庫表

目錄 1.若沒有Maven項目,可以選擇新建 2.添加Maven依賴 3.數據庫的創建 3.1 新建連接 --> 創建數據庫 3.2 創建數據庫表 4.連接數據庫 1.若沒有Maven項目,可以選擇新建 步驟一:點擊 File --> New --> Project 步驟二&#xf…

請求庫-axios

Axios 是一個基于 Promise 的 HTTP 客戶端庫,用于瀏覽器和 Node.js 環境。它支持發送異步 HTTP 請求,并提供了簡潔的 API 來處理請求和響應。1、安裝axios因為axios是一個第三方庫,所以在使用之前我們需要先安裝第三方模塊。安裝 Axios 需通過…

電子煙的4種屏幕驅動集成語音方案介紹

目前電子煙在全球市場的表現非常不錯,很多國產電子煙廠家都有非常不錯的產品,而屏幕驅動方案是電子煙智能化的重要組成部分,今天就給大家帶來電子煙的4種主流屏幕驅動方案(含2025年最新版方案)。?  方案一、LED顯示方案語音播報集成方案 W…

無法加載 DLL“xxxxxxx.dll”: 找不到指定的模塊。 (異常來自 HRESULT:0x8007007E)。

(無法加載 DLL“xxxxxxx.dll”: 找不到指定的模塊。 (異常來自 HRESULT:0x8007007E)。) 這個錯誤: 無法加載 DLL“ZH_P2P_Libx64.dll”: 找不到指定的模塊。 (異常來自 HRESULT:0x8007007E) 意味著你的程序在運行時試圖加載一個名為 xxxxxxx.dll 的動態鏈接庫&#…

Flask/Django 生產部署:Gunicorn vs Nginx,Windows 與 Linux 實戰指引

Flask/Django 生產部署:Gunicorn vs Nginx,Windows 與 Linux 實戰指引 TL;DR Gunicorn:Python WSGI 應用服務器,運行 Flask/Django(Linux 用)。Nginx:反向代理/網關(TLS、靜態、限流…

Nginx 優化與防盜鏈全解析:從性能調優到資源保護

Nginx 優化與防盜鏈全解析:從性能調優到資源保護 文章目錄Nginx 優化與防盜鏈全解析:從性能調優到資源保護一、基礎安全優化:隱藏版本號1.1 查看當前版本號1.2 兩種隱藏/修改方案方案一:修改配置文件(快速隱藏&#xf…

HOT100--Day20--39. 組合總和,22. 括號生成,79. 單詞搜索

HOT100–Day20–39. 組合總和,22. 括號生成,79. 單詞搜索 每日刷題系列。今天的題目是《力扣HOT100》題單。 題目類型:回溯。 關鍵:掌握排列,組合。記得回溯。可以重復選的話,下一層index從哪里開始&#x…

高并發場景下的“命令執行”注入繞道記

環境:CentOS 8 OpenResty 1.21 PHP-FPM 8.0 背景:營銷團隊上線了一個“圖片裁剪”接口,參數直接拼進 shell_exec,結果被打成“礦機”。1. 發現:流量突增 30 倍,卻不見數據庫慢查詢 iftop -i eth0出站 1.8…

【modbus學習】

Modbus通信(源于施耐德)串行鏈路:RTU(傳輸大量數據,適合工業)、ASCII(少量數據,適合計算機)TCP/IP:TCP(傳輸嚴謹,效率低)、…

Redis單線程模型為什么快?

Redis的單線程模型指的是redis只使用一個線程來出來所有的命令式指令,但是不是意味著redis內部就只使用一個線程來處理所有的任務。都知道redis是一個客戶端-服務器的程序,那么redis就只有一個服務器,但是有多個客戶端,就像mysql一…

前端安全攻防:XSS, CSRF 等常見威脅的防范與檢測指南

在如今高度互聯的 Web 應用世界里,前端安全不再是可有可無的選項,而是構建可信賴、健壯應用的基石。隨著 Web 技術的發展,攻擊者們也變得越來越狡猾,前端遭受的攻擊手段層出不窮。其中,跨站腳本攻擊 (XSS) 和跨站請求偽…

Scikit-learn Python機器學習 - 特征降維 壓縮數據 - 特征選擇 - 移除低方差特征(VarianceThreshold)

鋒哥原創的Scikit-learn Python機器學習視頻教程: 2026版 Scikit-learn Python機器學習 視頻教程(無廢話版) 玩命更新中~_嗶哩嗶哩_bilibili 課程介紹 本課程主要講解基于Scikit-learn的Python機器學習知識,包括機器學習概述,特征工程(數據…

C#(鏈表創建與原地反轉)

鏈表創建(C#) 在C#中,鏈表可以通過自定義節點類實現。每個節點包含數據域和指向下一個節點的引用。 public class ListNode {public int val;public ListNode next;public ListNode(int val0, ListNode nextnull) {this.val val;this.next…

Android --- AOSP源碼導入Android Studio

AOSP代碼量龐大,為了開發的方便,我們需要導入到android studio中,其中關鍵的一 項就是配置跳轉。尤其是對于Framework開發來說生成 ipr,iml 工程文件make idegen ./development/tools/idegen/idegen.sh會生成如下文件首先需要修改ipr和iml文件…

游戲中的設計模式——第一篇 設計模式簡介

前言 對于設計模式,相信很多開發者并不陌生,我在學習過程中希望把自己的一些總結和心得體會與你分享。 本專欄主要將重點放在設計模式在游戲中的應用,會結合大家熟悉的游戲場景和功能闡述設計模式在該處應用的好處。因為設計模式很多&#xf…

SpringBoot + RustFS 實現文件切片極速上傳技術

本文將手把手教你如何通過 SpringBoot 和 RustFS 構建高性能文件切片上傳系統,解決大文件傳輸的痛點,實現秒傳、斷點續傳和分片上傳等高級功能。 目錄 一、為什么選擇 RustFS SpringBoot? 二、環境準備與部署 2.1 安裝 RustFS 2.2 Sprin…

在Word和WPS文字中便捷切換英文段落大小寫

在Word和WPS文字中編輯英文段落時,有時候英文字母的大小寫不規范,或者需要把某一段全部改為大寫字母怎么辦?使用ShiftF3組合鍵即可快速在三種模式中切換:全部大寫、全部小寫、首字母大寫——其中首字母大寫的Word是每一句話的第一…

成都金牛區哪里租好辦公室?國際數字影像產業園享稅收優惠

在成都金牛區租賃優質辦公室,國際數字影像產業園憑借其享有的稅收優惠政策,成為了許多企業的首選之地。稅收優惠對于租賃辦公室的企業來說,是一筆不小的成本節省。國際數字影像產業園針對入駐企業提供的稅收優惠政策,能在企業運營…

CSS `:is()` `:where()` 實戰指南:簡化選擇器,提升可維護性

🎯 CSS :is() & :where() 實戰指南:簡化選擇器,提升可維護性你是否在項目中寫過一大串重復的選擇器?比如: h1, h2, h3, h4, h5, h6 { margin-bottom: 1rem; }這樣的代碼既冗長又難維護。 現在 CSS 提供了 :is() 和…

Linux I/O 訪問架構深入分析

Linux I/O 訪問架構深入分析 目錄 概述I/O 架構層次核心數據結構I/O 處理流程VFS 虛擬文件系統塊設備I/O字符設備I/O內存映射I/O異步I/O機制I/O調度器調試工具與方法性能優化策略 概述 Linux I/O 系統是一個多層次、高度抽象的架構,旨在為應用程序提供統一的文件訪問…