讀SQL學習指南(第3版)筆記07_分組和子查詢

来源:https://www.cnblogs.com/lying7/archive/2023/08/30/17664818.html
-Advertisement-
Play Games

![](https://img2023.cnblogs.com/blog/3076680/202308/3076680-20230829150529122-415016074.png) # 1. 數據通常以資料庫用戶所需的最低層級的粒度存儲 # 2. 分組 ## 2.1. 隱式分組 ### 2.1. ...


1. 數據通常以資料庫用戶所需的最低層級的粒度存儲

2. 分組

2.1. 隱式分組

2.1.1. mysql

-> SELECT MAX(amount) max_amt,
    ->   MIN(amount) min_amt,
    ->   AVG(amount) avg_amt,
    ->   SUM(amount) tot_amt,
    ->   COUNT(*) num_payments
    -> FROM payment;

2.1.1.1. 查詢返回的每個值都是由聚合函數生成的

2.1.1.2. 沒有使用group by子句

2.1.1.3. 只有一個隱式分組

2.1.1.3.1. payment數據表中的所有行

2.2. 顯式分組

2.2.1. mysql

-> SELECT customer_id,
    ->   MAX(amount) max_amt,
    ->   MIN(amount) min_amt,
    ->   AVG(amount) avg_amt,
    ->   SUM(amount) tot_amt,
    ->   COUNT(*) num_payments
    -> FROM payment
    -> GROUP BY customer_id;

2.2.1.1. 添加一個group by子句來指定聚合函數應該應用於哪個分組

2.3. 單列分組

2.3.1. 最簡單,也是最常用的分組類型

2.3.2. mysql

-> SELECT actor_id, count(*)
    -> FROM film_actor
    -> GROUP BY actor_id;

2.4. 多列分組

2.4.1. 需要跨越多列生成分組

2.4.2. mysql

-> SELECT fa.actor_id, f.rating, count(*)
    -> FROM film_actor fa
    ->   INNER JOIN film f
    ->   ON fa.film_id = f.film_id
    -> GROUP BY fa.actor_id, f.rating
    -> ORDER BY 1,2;

2.5. 通過表達式分組

2.5.1. 根據表達式產生的值構建分組

2.5.2. mysql

-> SELECT extract(YEAR FROM rental_date) year,
    ->   COUNT(*) how_many
    -> FROM rental
    -> GROUP BY extract(YEAR FROM rental_date);

2.6. 分組過濾條件

2.6.1. 由於group by子句是在where子句被評估之後運行的,因此無法為此對where子句增加過濾條件

2.6.2. 無法在where子句中引用聚合函數count(*)

2.6.2.1. 因為在評估where子句時,分組尚未生成,因而必須將分組過濾條件放入having子句

2.6.3. 向包含group by子句的查詢中添加過濾條件時,仔細考慮是過濾原始數據(將過濾條件放入where子句),還是過濾分組後的數據(將過濾條件放入having子句)

3. 聚合函數

3.1. 對分組中的所有行執行特定的操作

3.2. max()

3.2.1. 返回集合中的最大值

3.3. min()

3.3.1. 返回集合中的最小值

3.4. avg()

3.4.1. 返回集合中的平均值

3.5. sum()

3.5.1. 返回集合中所有值之和

3.6. count()

3.6.1. 返回集合中所有值的個數

4. 統計不同的值

4.1. mysql

-> SELECT COUNT(customer_id) num_rows,
    ->   COUNT(DISTINCT customer_id) num_customers
    -> FROM payment;

4.2. 通過指定distinct,count()函數檢查分組中每個成員的列值,以便查找和刪除重覆項,而不是簡單地計算分組中值的數量

4.3. mysql

-> SELECT COUNT(*) num_rows,
    ->   COUNT(val) num_vals,
    ->   SUM(val) total,
    ->   MAX(val) max_val,
    ->   AVG(val) avg_val
    -> FROM number_tbl;

4.4. count(*)統計行數

4.5. count(val)統計val列包含多少個值並且忽略所有遇到的null值

5. 使用表達式

5.1. mysql

-> SELECT MAX(datediff(return_date,rental_date))
    -> FROM rental;

5.2. 除了使用列作為聚合函數的參數,也可以使用表達式

6. 生成彙總

6.1. 假設在計算每位演員/評級組合的總計數的同時,還想知道不同演員參演的電影總數,這時可以運行一個額外的查詢併合並結果

6.2. with rollup選項來讓資料庫伺服器完成這些工作

6.3. mysql

-> SELECT fa.actor_id, f.rating, count(*)
    -> FROM film_actor fa
    ->   INNER JOIN film f
    ->   ON fa.film_id = f.film_id
    -> GROUP BY fa.actor_id, f.rating WITH ROLLUP
    -> ORDER BY 1,2;

6.4. Oracle Database

6.4.1. GROUP BY ROLLUP(fa.actor_id, f.rating)

6.4.2. 可以在group_by子句中對部分列彙總

6.4.3. 如果按照列a、b、c進行分組,可以指示伺服器通過下列語句僅對列b和c執行彙總

6.4.3.1. GROUP BY a, ROLLUP(b, c)

6.5. with cube選項

6.5.1. 為分組列的所有可能的組合生成彙總行

6.5.2. MySQL 8.0版並未提供

6.5.3. SQL Server和Oracle Database中可以使

7. 子查詢

7.1. 子查詢總是被包圍在括弧中,通常先於包含語句執行

7.2. 子查詢像是一個具有語句作用域的臨時數據表(這意味著伺服器在執行SQL語句後會清空分配給子查詢結果的記憶體)

7.3. 如果不清楚子查詢究竟做了什麼,可以單獨運行子查詢(不加括弧)並查看返回結果

7.4. 返回的結果集

7.4.1. 單行單列

7.4.2. 多行單列

7.4.2.1. in和not in運算符

7.4.2.1.1. 雖然不能把單個值與一組值進行相等比較,但是可以檢查這個值能否包含在一組值中
7.4.2.1.2. mysql
-> SELECT country_id
    -> FROM country
    -> WHERE country IN ('Canada','Mexico');
7.4.2.1.3. mysql
-> SELECT city_id, city
    -> FROM city
    -> WHERE country_id IN
    ->  (SELECT country_id
    ->   FROM country
    ->   WHERE country IN ('Canada','Mexico'));
7.4.2.1.4. sql
SELECT first_name, last_name
FROM customer
WHERE customer_id NOT IN
 (SELECT customer_id
  FROM payment
  WHERE amount = 0)
7.4.2.1.4.1. not in的版本更易於理解

7.4.2.2. all運算符

7.4.2.2.1. 將某個值與集合中的所有值進行比較
7.4.2.2.2. mysql
-> SELECT first_name, last_name
    -> FROM customer
    -> WHERE customer_id <> ALL
    ->  (SELECT customer_id
    ->   FROM payment
    ->   WHERE amount = 0);

7.4.2.3. any運算符

7.4.2.3.1. 允許將單個值與一組值中的各個值進行比較
7.4.2.3.2. 只要有一次比較成立,使用any運算符的條件即為真
7.4.2.3.3. any與in等效

7.4.2.4. 使用not in或<>運算符比較一個值和一組值時,必須確保這組值中不包含null值,這是因為伺服器會將表達式左側的值與組中的各個值進行比較,任何值與null作相等比較時都會產生unknown

7.4.3. 多行多列

7.4.3.1. mysql

-> SELECT fa.actor_id, fa.film_id
    -> FROM film_actor fa
    -> WHERE fa.actor_id IN
    ->  (SELECT actor_id FROM actor WHERE last_name = 'MONROE')
    ->   AND fa.film_id IN
    ->  (SELECT film_id FROM film WHERE rating = 'PG');

7.4.3.2. 可以將兩個單列子查詢合併成一個多列子查詢

7.4.3.3. mysql

-> SELECT actor_id, film_id
    -> FROM film_actor
    -> WHERE (actor_id, film_id) IN
    ->  (SELECT a.actor_id, f.film_id
    ->   FROM actor a
    ->      CROSS JOIN film f
    ->   WHERE a.last_name = 'MONROE'
    ->   AND f.rating = 'PG');

7.4.3.4. 過濾條件必須將film_actor數據表的兩列放入括弧內

7.4.3.5. 與子查詢返回的順序一致

7.4.3.6. 子查詢使用了交叉連接

7.5. 子查詢類型

7.5.1. 非關聯子查詢

7.5.1.1. 子查詢完全獨立

7.5.1.2. 單獨執行,不會引用包含語句中的任何內容

7.5.2. 關聯子查詢

7.5.2.1. 子查詢會引用包含語句中的列

7.5.2.2. 並不是先於包含語句一次性執行完畢,而是為每一個候選行(可能會包含在最終結果中)執行一次

7.5.2.2.1. 如果包含查詢返回很多行,將會引發性能問題

7.5.2.3. 在MySQL的delete語句中使用關聯子查詢時,無論如何都不能使用數據表別名,這就是在子查詢中使用數據表全名的原因

7.6. exists運算符

7.6.1. 子查詢可能會返回0行、1行或者多行結果,然而條件只是簡單地檢查子查詢是否返回至少1行

7.6.2. 慣例是指定select 1或select

7.6.3. 也可以使用not exists來檢查沒有返回行的子查詢

8. 何時使用子查詢

8.1. 子查詢作為數據源

8.1.1. 數據加工

8.1.1.1. 如果使用子查詢,你就能夠遵守僅在有明確的存儲新數據的業務需求時才向資料庫添加新數據表的原則

8.1.2. 面向任務的子查詢

8.1.3. 公用表表達式

8.1.3.1. Common table expression,CTE

8.1.3.2. MySQL 8.0版新引入的特性

8.1.3.3. CTE是一個具名子查詢,出現在with子句內查詢的頂部,該子句可以包含多個以逗號分隔的CTE

8.1.3.4. 使用臨時數據表來存儲後續查詢要用到的查詢結果的替代方案

8.2. 子查詢作為表達式生成器


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ### 前言 在非同步編程中,處理非同步操作之間的數據流轉是一個比較常用的操作。`C#`非同步編程提供了一個強大的工具來解決這個問題,那就是`AsyncLocal`。它是一個線程本地存儲的機制,可以在非同步操作之間傳遞數據。它為我們提供了一種簡單而可靠的方式來共用數據,而不必擔心線程切換或非同步上下文的變化。 ...
  • 本文將分享使用 GitHub Actions 完成對一個.Net Core+Vue 的前後端分離項目 zhontai 的構建,並使用 docker 部署到雲伺服器(阿裡雲),及對docker部署.Net Core+Vue的一些經驗分享。 ...
  • [toc] # Linux運維工程師面試題(4) > 祝各位小伙伴們早日找到自己心儀的工作。 > 持續學習才不會被淘汰。 > 地球不爆炸,我們不放假。 > 機會總是留給有有準備的人的。 > 加油,打工人! ## 1 redis 常用的數據類型 - String:字元串,最基礎的數據類型 - List ...
  • # sendto errno -11代碼分析 errno -11在內核代碼中代表EAGAIN(再試⼀次),域套接字sendto過程中` sendto->sock_sendmsg->unix_dgram_sendmsg`,在`unix_dgram_sendmsg`中有兩處會返回 EAGAIN: 第1處 ...
  • 哈嘍大家好,我是鹹魚 今天這篇文章介紹如何在一臺伺服器(以 CentOS 7.9 為例)上通過 `redis-trib.rb` 工具搭建 Redis cluster (三主三從) `redis-trib.rb` 是一個基於 Ruby 編寫的腳本,其功能涵蓋了創建、管理以及維護 Redis 集群的各個 ...
  • 本文首先介紹了進程的控制結構,即進程式控制制塊(PCB),它是表示進程的數據結構,包含了進程的相關信息和資源。PCB之間通過鏈表連接,形成就緒隊列和阻塞隊列,用於進程調度和資源管理。接著,文章詳細探討了進程的切換過程。進程切換是為了保證公平分配CPU時間片,涉及保存和恢復進程的執行上下文、更新進程狀態和... ...
  • atexit 註冊的處理器中可以再調 atexit 或 exit 嗎?putenv 或 setenv 增加一個環境變數後 environ 指針地址為什麼變了?setjmp & longjmp 跨函數跳轉後自動變數為什麼回退了?設置 RLIMIT_NPROC 為 10 為何連一個子進程也 fork 不... ...
  • # 查看文件夾大小 ## ls 命令 > 列出當前工作目錄下的所有文件/文件夾的名稱 使用`ls -l`,會顯示成位元組大小,`ls- lh`會以KB、MB等為單位進行顯示更加直觀 ![](https://img2023.cnblogs.com/blog/431942/202308/431942-20 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...