讀SQL進階教程筆記04_集合運算

来源:https://www.cnblogs.com/lying7/archive/2023/04/01/17277846.html
-Advertisement-
Play Games

1. 集合論是SQL語言的根基 1.1. UNION 1.1.1. SQL-86標準 1.2. NTERSECT和EXCEPT 1.2.1. SQL-92標準 1.3. 除法運算(DIVIDE BY) 1.3.1. 沒有被標準化 2. 註意事項 2.1. SQL能操作具有重覆行的集合,可以通過可選項 ...


1. 集合論是SQL語言的根基

1.1. UNION

  • 1.1.1. SQL-86標準

1.2. NTERSECT和EXCEPT

  • 1.2.1. SQL-92標準

1.3. 除法運算(DIVIDE BY)

  • 1.3.1. 沒有被標準化

2. 註意事項

2.1. SQL能操作具有重覆行的集合,可以通過可選項ALL來支持

  • 2.1.1. 不允許重覆

    • 2.1.1.1. 直接使用UNION或INTERSECT

    • 2.1.1.2. 集合運算符為了排除掉重覆行,預設地會發生排序

  • 2.1.2. 允許重覆

    • 2.1.2.1. 加上可選項ALL

      2.1.2.1.1. 不會再排序,所以性能會有提升

      2.1.2.1.2. 非常有效的用於優化查詢性能的方法

    • 2.1.2.2. UNION ALL

      2.1.2.2.1. 不具有冪等性

2.2. 集合運算符有優先順序

  • 2.2.1. INTERSECT比UNION和EXCEPT優先順序更高

  • 2.2.2. 括弧明確地指定運算順序

2.3. 各個DBMS提供商在集合運算的實現程度上參差不齊

  • 2.3.1. SQL Server從2005版開始支持INTERSECT和EXCEPT

  • 2.3.2. Oracle這樣,實現了EXCEPT功能但卻命名為MINUS的資料庫

  • 2.3.3. INTERSECT和EXCEPT不能在MySQL里執行

2.4. 除法運算沒有標准定義

  • 2.4.1. 四則運算里的和(UNION)、差(EXCEPT)、積(CROSS JOIN)都被引入了標準SQL

3. 檢查集合相等性

3.1. “相等”指的是行數和列數以及內容都相同

3.2. “是同一個集合”

3.3. 原理1

  • 3.3.1. S UNION S = S

  • 3.3.2. 冪等性(indempotency)

    • 3.3.2.1. 抽象代數里群論等理論中的概念

    • 3.3.2.2. 二目運算符對任意S,都有SS = S成立”

3.4. 示例1

  • 3.4.1.
  SELECT COUNT(*) AS row_cnt
     FROM ( SELECT *
             FROM tbl_A
           UNION
           SELECT *
             FROM tbl_B ) TMP;
  • 3.4.2. 這個查詢的結果與tbl_A及tbl_B的行數一致,則兩張表是相等的

  • 3.4.3. 表tbl_A和表tbl_B的行數是一樣的

    • 3.4.3.1. 如果行數不一樣,那就不需要比較其他的了

3.5. 原理2

  • 3.5.1. 如果A UNION B = A INTERSECT B,則集合A和集合B相等

  • 3.5.2. (A UNION B) EXCEPT (A INTERSECT B)的結果集是不是空集就可以了

  • 3.5.3. INTERSECT

    • 3.5.3.1. 冪等性(indempotency)
  • 3.5.4. EXCEPT不具有冪等性

3.6. 示例2

  • 3.6.1. --兩張表相等時返回“相等”,否則返回“不相等”
   SELECT CASE WHEN COUNT(*) = 0
               THEN ’相等’
               ELSE’不相等’END AS result
     FROM ((SELECT * FROM  tbl_A
           UNION
           SELECT * FROM  tbl_B)
           EXCEPT
           (SELECT * FROM  tbl_A
           INTERSECT
           SELECT * FROM  tbl_B)) TMP;
  • 3.6.2. 改進版不需要事先查詢兩張表的行數

  • 3.6.3. 需要進行4次排序(3次集合運算加上1次DISTINCT)

    • 3.6.3.1. 性能會有所下降

3.7. 示例3

  • 3.7.1. --用於比較表與表的diff
   (SELECT * FROM  tbl_A
    EXCEPT
    SELECT * FROM  tbl_B)
   UNION ALL
   (SELECT * FROM  tbl_B
    EXCEPT
    SELECT * FROM  tbl_A);

4. 用差集實現關係除法運算

4.1. 嵌套使用NOT EXISTS

4.2. 使用HAVING子句轉換成一對一關係

4.3. 把除法變成減法

  • 4.3.1. 示例

    • 4.3.1.1.


  • 4.3.1.2. --用求差集的方法進行關係除法運算(有餘數)
   SELECT DISTINCT emp
     FROM EmpSkills ES1
    WHERE NOT EXISTS
           (SELECT skill
             FROM Skills
           EXCEPT
           SELECT skill
             FROM EmpSkills ES2
             WHERE ES1.emp = ES2.emp);
  • 4.3.1.3. 關聯子查詢是為了使SQL能夠實現類似面向過程語言中迴圈的功能而引入的

5. 尋找相等的子集

5.1. IBM過去研製的第一個關係資料庫實驗系統——System R

  • 5.1.1. 用CONTAINS這一謂詞來檢查集合間的包含關係

  • 5.1.2. 後來因為性能原因被刪除掉了,直到現在也沒有恢復

  • 5.1.3.

SELECT 'A CONTAINS B'

     FROM SupParts
    WHERE (SELECT part
             FROM SupParts
           WHERE  sup ='A')
             CONTAINS
                 (SELECT part
                   FROM SupParts
                   WHERE  sup ='B')

5.2. 示例

  • 5.2.1. --生成供應商的全部組合
   SELECT SP1.sup AS s1, SP2.sup AS s2
     FROM SupParts SP1, SupParts SP2
    WHERE SP1.sup < SP2.sup
    GROUP BY SP1.sup, SP2.sup;
  • 5.2.2.
SELECT SP1.sup AS s1, SP2.sup AS s2

     FROM SupParts SP1, SupParts SP2
    WHERE SP1.sup < SP2.sup                  --生成供應商的全部組合
     AND SP1.part = SP2.part                --條件1:經營同種類型的零件
    GROUP BY SP1.sup, SP2.sup
   HAVING COUNT(*) = (SELECT COUNT(*)       --條件2:經營的零件種類數相同
                       FROM SupParts SP3
                       WHERE SP3.sup = SP1.sup)
     AND COUNT(*) = (SELECT COUNT(*)
                       FROM SupParts SP4
                       WHERE SP4.sup = SP2.sup);
  • 5.2.3. SQL在比較兩個集合時,並不是以行為單位來比較的,而是把集合當作整體來處理的

6. 用於刪除重覆行的高效SQL

6.1. --刪除重覆行:使用關聯子查詢

    DELETE FROM Products
     WHERE rowid < ( SELECT MAX(P2.rowid)
                      FROM Products P2
                      WHERE Products.name  = P2. name
                        AND Products.price = P2.price ) ;

6.2. --用於刪除重覆行的高效SQL語句(1):通過EXCEPT求補集

    DELETE FROM Products
     WHERE rowid IN ( SELECT rowid           --全部rowid
                        FROM Products
                      EXCEPT                 --減去
                      SELECT MAX(rowid)     --要留下的rowid
                        FROM Products
                      GROUP BY name, price) ;

6.3. --刪除重覆行的高效SQL語句(2):通過NOT IN求補集

    DELETE FROM Products
     WHERE rowid NOT IN ( SELECT MAX(rowid)
                            FROM Products
                          GROUP BY name, price);
  • 6.3.1. 不支持EXCEPT的資料庫也可以使用

6.4. 實現了行ID的資料庫只有Oracle和PostgreSQL

  • 6.4.1. PostgreSQL里的相應名字是oid,如果要使用,需要事先在CREATE TABLE的時候指定可選項WITH OIDS

  • 6.4.2. 如果其他資料庫想要使用這些SQL,則需要在表中創建類似的具有唯一性的“id”列


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

-Advertisement-
Play Games
更多相關文章
  • 前言 最近電腦重新安裝nmap,但是圖形化界面無法運行,如圖所示: 是因為用戶名稱中存在中文字元。 接下來就親自實操一下如何將Windows操作系統用戶名的中文名稱修改為英文名稱。 一、控制面板修改電腦名 (1):桌面左下角搜索框搜索控制面板(2):打開控制面板,點擊用戶帳戶下的更改賬戶類型 (3) ...
  • 今天鹹魚給大家分享個源碼編譯安裝 Nginx 的 shell 腳本 這個 shell 腳本可重覆執行 完整源碼放在最後 定義一個變數來存放 nginx 版本號 version=1.15.4 nginx 下載地址:http://nginx.org/download/ 下列函數功能則是判斷當前步驟是否執 ...
  • 一、為什麼要線程同步 在Linux 多線程編程中,線程同步是一個非常重要的問題。如果線程之間沒有正確地同步,就會導致程式出現一些意外的問題,例如: 競態條件(Race Condition):多個線程同時修改同一個共用變數,可能會導致不可預測的結果,因為線程的執行順序是不確定的。 死鎖(Deadloc ...
  • 這篇主要介紹對於SOP8,SOP10,SOP16封裝的PY32F002A/PY32F003, 沒有BOOT0的情況如何修改Option Bytes, 以及如何在物理管腳上使用不同的PIN ...
  • 訪問命令行(command line interface,CLI) Linux控制台 1)Linux系統啟動時,會自動創建多個虛擬控制台。虛擬控制台是運行在Linux系統記憶體中的終端會話。多數Linux發行版會啟動5~6個 2)通常必須按下Ctrl+Alt組合鍵,然後再按一個功能鍵(F1~F7)來進 ...
  • 資料庫安全與保護 第一節 資料庫完整性 資料庫完整性是指資料庫中數據的正確性和相容性。 數據完整性約束是為了防止資料庫中存在不符合語義的數據,為了維護數據的完整性,DBMS 必須提供一種機制來檢查資料庫中的數據,以判斷其是否滿足語義規定的條件。 這些加在資料庫數據之上的語義約束條件就是數據完整性約束 ...
  • 包含五個內容:①Navicat連接伺服器MySQL;②如何查看MySQL用戶名和密碼;③修改MySQL登錄密碼;④error 1045 (28000): access denied for user 'root'@'localhost' (using password:yes)錯誤解決方法;⑤安裝M... ...
  • 一:在hadoop3.3中安裝配置sqoop1.4.7 前言: sqoop功能已經非常完善了,沒有什麼可以更新的了,官方停止更新維護了。因此官方集成的hadoop包停留在了2.6.0版本,在hadoop3.3.0版本會提示類版本過低錯誤,但純凈版sqoop有缺少必須的第三方庫,所以將這兩個包下載下來 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...