讀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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...