選讀SQL經典實例筆記16_邏輯否定

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

![](https://img2023.cnblogs.com/blog/3076680/202308/3076680-20230802124620904-1514854566.png) # 1. 示例數據 ## 1.1. student ```sql insert into student val ...


1. 示例數據

1.1. student

insert into student values (1,'AARON',20)
insert into student values (2,'CHUCK',21)
insert into student values (3,'DOUG',20)
insert into student values (4,'MAGGIE',19)
insert into student values (5,'STEVE',22)
insert into student values (6,'JING',18)
insert into student values (7,'BRIAN',21)
insert into student values (8,'KAY',20)
insert into student values (9,'GILLIAN',20)
insert into student values (10,'CHAD',21)

1.2. courses

insert into courses values ('CS112','PHYSICS',4)
insert into courses values ('CS113','CALCULUS',4)
insert into courses values ('CS114','HISTORY',4)

1.3. professor

insert into professor values ('CHOI','SCIENCE',400,45)
insert into professor values ('GUNN','HISTORY',300,60)
insert into professor values ('MAYER','MATH',400,55)
insert into professor values ('POMEL','SCIENCE',500,65)
insert into professor values ('FEUER','MATH',400,40)

1.4. take

insert into take values (1,'CS112')
insert into take values (1,'CS113')
insert into take values (1,'CS114')
insert into take values (2,'CS112')
insert into take values (3,'CS112')
insert into take values (3,'CS114')
insert into take values (4,'CS112')
insert into take values (4,'CS113')
insert into take values (5,'CS113')
insert into take values (6,'CS113')
insert into take values (6,'CS114')

1.5. teach

insert into teach values ('CHOI','CS112')
insert into teach values ('CHOI','CS113')
insert into teach values ('CHOI','CS114')
insert into teach values ('POMEL','CS113')
insert into teach values ('MAYER','CS112')
insert into teach values ('MAYER','CS114')

2. 問題1:沒有選修過CS112課程的學生

2.1. sql

select *
  from student
 where sno in ( select sno
                  from take
                 where cno != 'CS112' )

2.2. sql

select *
  from student
 where sno not in (select sno
                     from take
                    where cno = 'CS112')

2.3. 要記住真正的邏輯否定要求兩個步驟,即為了找出‘哪些人不是’,就要先找出‘哪些人是’,然後再排除掉他們

2.4. PostgreSQL

2.5. MySQL

2.6. 使用CASE表達式和聚合函數MAX標識一個學生是否選修了CS112課程

2.6.1. sql

select s.sno,s.sname,s.age
  from student s left join take t
    on (s.sno = t.sno)
 group by s.sno,s.sname,s.age
having max(case when t.cno = 'CS112'
                then 1 else 0 end) = 0

2.7. Oracle

2.7.1. group by解決方案

select s.sno,s.sname,s.age
   from student s, take t
  where s.sno = t.sno (+)
  group by s.sno,s.sname,s.age
 having max(case when t.cno = 'CS112'
                 then 1 else 0 end) = 0

2.7.2. 視窗函數解決方案

select distinct sno,sname,age
   from (
 select s.sno,s.sname,s.age,
        max(case when t.cno = 'CS112'
                 then 1 else 0 end)
        over(partition by s.sno,s.sname,s.age) as takes_CS112
   from student s, take t
  where s.sno = t.sno (+)
        ) x
  where takes_CS112 = 0

2.8. DB2

2.9. SQL Server

2.10. 使用CASE表達式和視窗函數MAX OVER

2.10.1. sql

select distinct sno,sname,age
  from (
select s.sno,s.sname,s.age,
       max(case when t.cno = 'CS112'
                then 1 else 0 end)
       over(partition by s.sno,s.sname,s.age) as takes_CS112
  from student s, take t
    on (s.sno = t.sno)
       ) x
 where takes_CS112 = 0

2.11. 外連接到TAKE表是為了確保把那些沒有選修任何課程的學生也能被篩選出來

2.12. 調用MAX函數找出最大的CASE表達式返回值

3. 問題2:只選修了CS112和CS114中的一門,而不是兩門都選的學生

3.1. sql

select *
  from student
 where sno in ( select sno
                  from take
                 where cno != 'CS112'
                   and cno != 'CS114' )

3.2. sql

select *
  from student s, take t
 where s.sno = t.sno
   and t.cno in ( 'CS112', 'CS114' )
   and s.sno not in ( select a.sno
                      from take a, take b
                     where a.sno = b.sno
                       and a.cno = 'CS112'
                       and b.cno = 'CS114' )

3.3. 使用自連接找出同時選修了CS112和CS114的學生

3.4. 使用子查詢從選修了CS112或CS114的學生中把同時選了兩門的學生剔除掉

3.5. DB2

3.6. Oracle

3.7. SQL Server

3.8. CASE表達式和視窗函數SUM OVER

3.8.1. sql

select distinct sno,sname,age
  from (
select s.sno,s.sname,s.age,
       sum(case when t.cno in ('CS112','CS114') then 1 else 0 end)
       over (partition by s.sno,s.sname,s.age) as takes_either_or
  from student s, take t
 where s.sno = t.sno
       )x
 where takes_either_or = 1

3.9. PostgreSQL

3.10. MySQL

3.11. CASE表達式和聚合函數SUM

3.11.1. sql

select s.sno,s.sname,s.age
  from student s, take t
 where s.sno = t.sno
 group by s.sno,s.sname,s.age
having sum(case when t.cno in ('CS112','CS114')
                then 1 else 0 end) = 1

3.12. 內連接STUDENT表和TAKE表,這樣就排除了那些沒有選修任何課程的學生

3.13. 使用CASE表達式標記一個學生是否選修了這兩門課程中的一門

3.14. 函數SUM會把每個學生對應的1都累加起來

4. 問題3:選修了CS112,而且沒有選修其他課程的學生

4.1. sql

select s.*
  from student s, take t
 where s.sno = t.sno
   and t.cno = 'CS112'

4.2. sql

select s.*
  from student s, take t
 where s.sno = t.sno
   and s.sno not in ( select sno
                        from take
                       where cno != 'CS112' )

4.3. 子查詢負責找出至少選修了一門課,但又沒有選修CS112的所有學生

4.4. 外層查詢負責找出選修了一門課程(任意課程),並且不在上述子查詢的返回結果的學生

4.5. STUDENT表和TAKE表之間的連接操作過濾掉沒有選修任何課程的學生

4.6. PostgreSQL

4.7. MySQL

4.8. 使用聚合函數COUNT確保下列查詢返回的學生只選修了一門課程

4.8.1. sql

select s.*
  from student s,
       take t1,
       (
select sno
   from take
 group by sno
having count(*) = 1
       ) t2
 where s.sno  = t1.sno
   and t1.sno = t2.sno
   and t1.cno = 'CS112'

4.8.2. 使用內嵌視圖T2找出只選修了一門課程的學生

4.8.3. 連接內嵌視圖T2到TAKE表,並且篩選出選修CS112課程的學生

4.8.4. 在內嵌視圖T2和TAKE表連接查詢的基礎上再次連接STUDENT表,找出匹配的學生

4.9. DB2

4.10. Oracle

4.11. SQL Server

4.12. 使用視窗函數COUNT OVER

4.12.1. sql

select sno,sname,age
  from (
select s.sno,s.sname,s.age,t.cno,
       count(t.cno) over (
         partition by s.sno,s.sname,s.age
       ) as cnt
  from student s, take t
 where s.sno = t.sno
       ) x
 where cnt = 1
   and cno = 'CS112'

4.12.2. 視窗函數解決方案處理方式上稍有不同(更有效率)

4.12.3. 內嵌視圖X返回了每一個學生、他們選修的課程以及他們選修了幾門課程

4.12.4. 獲得了每個學生選修的課程和課程數目之後,最後只要保留CNT等於1並且CNO等於CS112的行即可


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

-Advertisement-
Play Games
更多相關文章
  • ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 本篇概覽 - 本文是《quarkus依賴註入》系列的第 ...
  • 我的一位朋友前陣子遇到一個問題,問題的核心就是try……catch……finally中catch和finally代碼塊到底哪個先執。這個問題看起來很簡單,當然是“catch先執行、finally後執行”了?真的是這樣嗎? 有下麵一段C#代碼,請問這段代碼的執行結果是什麼? public static ...
  • # Unity IPreprocessBuildWithReport Unity IPreprocessBuildWithReport是Unity引擎中的一個非常有用的功能,它可以讓開發者在構建項目時自動執行一些操作,並且可以獲取構建報告。這個功能可以幫助開發者提高工作效率,減少手動操作的時間和錯誤 ...
  • # 個人博客-首頁排版優化 # 優化計劃 - [x] 置頂3個且可滾動或切換 - [ ] 推薦改為4個,然後新增歷史文章,將推薦的載入更多放入歷史文章,按文章發佈時間降序排列。 - [ ] 標簽功能,可以為文章貼上標簽 - [ ] 推薦點贊功能 本篇文章優化置頂 # 原先置頂如圖 ![image]( ...
  • # C#委托 太久沒用了,簡單的複習一下 快速過一遍語法使用 ## 使用委托的步驟 1.定義一個委托類型 只需要在聲明的前面加上delegate關鍵字,其他的就跟聲明一個方法(函數)類似 ~~~ public delegate void SayHello(string name); ~~~ 2.使用 ...
  • # Unity BuildPlayerProcessor Unity BuildPlayerProcessor是Unity引擎中的一個非常有用的功能,它可以讓開發者在構建項目時自動執行一些操作。這個功能可以幫助開發者提高工作效率,減少手動操作的時間和錯誤率。在本文中,我們將介紹Unity Build ...
  • module_init是linux內核提供的一個巨集, 可以用來在編寫內核模塊時註冊一個初始化函數, 當模塊被載入的時候, 內核負責執行這個初始化函數. 在編寫設備驅動程式時, 使用這個巨集看起來理所應當, 沒什麼特別的, 但畢竟我還是一個有點追求的程式員嘛:P, 這篇文章是我學習module_init... ...
  • 第一種 每打開一次終端都輸入一次 source /etc/profile,這樣就可以載入配置文件,環境變數自然就有了 第二種 輸入vim ./bashrc,在底部添加配置在/etc/profile里的配置,這樣就可以無需使用source命令載入了 也可以在./bashrc底部添加 source /e... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...