1. 程式人生 > >SQL進階——Having子句

SQL進階——Having子句

執行環境 win10 / oracle(DB11g)

1、可以出勤的隊伍

思路:
一個集合中,如果元素最大值和最小值相等,那麼這個集合中肯定只用一種值

-- 創表
create table teams_10
(
    member varchar(10),
    team_id integer,
    status1 varchar(10)
);

insert into teams_10 values('喬', 1, '待命');
insert into teams_10 values('肯', 1, '出勤中');
insert into teams_10 values
('米克', 1, '待命');
insert into teams_10 values('卡倫', 2, '出勤中'); insert into teams_10 values('凱斯', 2, '休息'); insert into teams_10 values('簡', 3, '待命'); insert into teams_10 values('哈特', 3, '待命'); insert into teams_10 values('迪克', 3, '待命'); insert into teams_10 values('貝斯', 4, '待命'); insert into teams_10 values
('阿倫', 5, '出勤中');
insert into teams_10 values('羅伯特', 5, '休息'); insert into teams_10 values('卡跟', 5, '待命');

SQL解決:

-- 1-直接找出可出勤的隊
select team_id
  from teams_10
 group by team_id
having max(status1) = '待命' 
   and min(status1) = '待命'
;

-- 2-對出勤的隊打標籤
select team_id
       ,case when max(status1) = '待命'
and min(status1) = '待命' then '全部在待命' else '隊長人手不夠' end as status1 from teams_10 group by team_id ;

結果:

-- 1
   TEAM_ID
----------
         4
         3


-- 2
   TEAM_ID STATUS1
---------- ------------
         1 隊長人手不夠
         2 隊長人手不夠
         4 全部在待命
         5 隊長人手不夠
         3 全部在待命

2、查詢重複的元素

-- 創表
create table materials_10
(
    center varchar(10),
    recieve_date date,
    material varchar(6)
)
;

insert into materials_10 values ('東京',to_date('2007-04-01','yyyy-mm-dd'),'錫');
insert into materials_10 values ('東京',to_date('2007-04-12','yyyy-mm-dd'),'鋅');
insert into materials_10 values ('東京',to_date('2007-05-17','yyyy-mm-dd'),'鋁');
insert into materials_10 values ('東京',to_date('2007-05-20','yyyy-mm-dd'),'鋅');
insert into materials_10 values ('大阪',to_date('2007-04-20','yyyy-mm-dd'),'銅');
insert into materials_10 values ('大阪',to_date('2007-04-22','yyyy-mm-dd'),'鎳');
insert into materials_10 values ('大阪',to_date('2007-04-29','yyyy-mm-dd'),'鉛');
insert into materials_10 values ('名古屋',to_date('2007-03-15','yyyy-mm-dd'),'鈦');
insert into materials_10 values ('名古屋',to_date('2007-04-01','yyyy-mm-dd'),'鋼');
insert into materials_10 values ('名古屋',to_date('2007-04-24','yyyy-mm-dd'),'鋼');
insert into materials_10 values ('名古屋',to_date('2007-05-02','yyyy-mm-dd'),'鎂');
insert into materials_10 values ('名古屋',to_date('2007-05-10','yyyy-mm-dd'),'鈦');
insert into materials_10 values ('福岡',to_date('2007-05-10','yyyy-mm-dd'),'鋅');
insert into materials_10 values ('福岡',to_date('2007-05-28','yyyy-mm-dd'),'錫');

SQL解決:

select center 
  from materials_10
 group by center
having count(material) <> count(distinct material)
;

結果:

CENTER
----------
名古屋
東京

用Having可以找出那個生產中心有存在重複材料生產,但是不能解決是哪一種材料重複了,為實現該目的,可以用exists ,他可以呈現更多的結果

select center, material
  from materials_10 m1
 where exists 
      (select * 
         from materials_10 m2 
        where m1.center = m2.center
          and m1.recieve_date <> m2.recieve_date 
          and m1.material = m2.material
      )
;

-- 結果
CENTER     MATERI
---------- ------
東京       鋅
東京       鋅
名古屋     鈦
名古屋     鋼
名古屋     鋼
名古屋     鈦

3、為集合設定詳細的條件

思路:
通過case表示式生成特徵函式,以滿足各種條件

-- 創表
create table testresults_10
(
    student_id varchar(4),
    classs varchar(2),
    sex varchar(4),
    score integer
)
;

insert into testresults_10 values('001','A','男',100);
insert into testresults_10 values('002','A','女',100);
insert into testresults_10 values('003','A','女',49);
insert into testresults_10 values('004','A','男',30);
insert into testresults_10 values('005','B','女',100);
insert into testresults_10 values('006','B','男',92);
insert into testresults_10 values('007','B','男',80);
insert into testresults_10 values('008','B','男',80);
insert into testresults_10 values('009','B','女',10);
insert into testresults_10 values('010','C','男',92);
insert into testresults_10 values('011','C','男',80);
insert into testresults_10 values('012','C','女',21);
insert into testresults_10 values('013','D','女',100);
insert into testresults_10 values('014','D','女',0);
insert into testresults_10 values('015','D','女',0);

SQL解決:

-- 查詢75%以上的學生分數都在80分以上的班級
select classs
  from testresults_10
 group by classs
having count(*)*0.75
       <= sum(case when score >=80 then 1 else 0 end)
;
-- 結果
CL
--
B


-- 查詢出分數在50分以上的男生的人數比分數在50分以上的女生多的班級
select classs
  from testresults_10
 group by classs
having sum(case when score >= 50 and sex = '男' then 1 else 0 end)
       > sum(case when score >= 50 and sex = '女' then 1 else 0 end)
;
-- 結果
CL
--
B
C

-- 查詢出女生平均分比男生平均分高的班級(對空集求平均為NULL)
select classs
  from testresults_10
 group by classs
having avg(case when sex = '男' then score end )
        < avg(case when sex = '女' then score end )
;
-- 結果
CL
--
A

練習

1、查重複

-- 創表
create table materials_10_t
(
    center varchar(10),
    recieve_date date,
    material varchar(6),
    orgland varchar(6)
)
;

insert into materials_10_t values ('東京',to_date('2007-04-01','yyyy-mm-dd'),'錫','智利');
insert into materials_10_t values ('東京',to_date('2007-04-12','yyyy-mm-dd'),'鋅','泰國');
insert into materials_10_t values ('東京',to_date('2007-05-17','yyyy-mm-dd'),'鋁','巴西');
insert into materials_10_t values ('東京',to_date('2007-05-20','yyyy-mm-dd'),'鋅','泰國');
insert into materials_10_t values ('大阪',to_date('2007-04-20','yyyy-mm-dd'),'銅','澳大利亞');
insert into materials_10_t values ('大阪',to_date('2007-04-22','yyyy-mm-dd'),'鎳','南非');
insert into materials_10_t values ('大阪',to_date('2007-04-29','yyyy-mm-dd'),'鉛','印度');
insert into materials_10_t values ('名古屋',to_date('2007-03-15','yyyy-mm-dd'),'鈦','玻利維亞');
insert into materials_10_t values ('名古屋',to_date('2007-04-01','yyyy-mm-dd'),'鋼','智利');
insert into materials_10_t values ('名古屋',to_date('2007-04-24','yyyy-mm-dd'),'鋼','阿根廷');
insert into materials_10_t values ('名古屋',to_date('2007-05-02','yyyy-mm-dd'),'鎂','智利');
insert into materials_10_t values ('名古屋',to_date('2007-05-10','yyyy-mm-dd'),'鈦','泰國');
insert into materials_10_t values ('福岡',to_date('2007-05-10','yyyy-mm-dd'),'鋅','美國');
insert into materials_10_t values ('福岡',to_date('2007-05-28','yyyy-mm-dd'),'錫','俄羅斯');

SQL解決:

-- 1、exists
select center, material, orgland
  from materials_10_t m1
 where exists 
      (select * 
         from materials_10_t m2 
        where m1.center = m2.center
          and m1.recieve_date <> m2.recieve_date 
          and m1.material = m2.material 
          and m1.orgland = m2.orgland
      )
;
-- 2、having
select center, orgland
  from materials_10_t
 group by center, orgland
having count(material) <> count(distinct material)
   and count(orgland)  <> count(distinct orgland)
;

結果:

-- 1
CENTER     MATERI ORGLAN
---------- ------ ------
東京       鋅     泰國
東京       鋅     泰國

-- 2
CENTER     ORGLAN
---------- ------
東京       泰國

2、多條件的特徵函式

(數學的分數在80分以上/語文的分數在50分以上)

-- 創表
create table testscores(
    student_id INTEGER,
    subject1    varchar(10),
    score       INTEGER
);
insert into testscores values(100, '數學', 100);
insert into testscores values(100, '語文', 80);
insert into testscores values(100, '理化', 80);
insert into testscores values(200, '數學', 80);
insert into testscores values(200, '語文', 95);
insert into testscores values(300, '數學', 40);
insert into testscores values(300, '語文', 90);
insert into testscores values(300, '社會', 55);
insert into testscores values(400, '數學', 80);

SQL解決:

-- 數學的分數在80分以上/語文的分數在50分以上
-- 回憶exists
select *
  from testscores t1
 where not EXISTS
        (  select *
             from testscores t2 
            where t1.student_id = t2.student_id
              and ( (subject1 = '數學' and score <= 80)
               or   (subject1 = '語文' and score <= 50) )
           )
;

-- 用having  空集為NULL
select student_id
  from testscores
 group by student_id
having 2 = sum(case when subject1 = '數學' and score > 80 then 1
                    when subject1 = '語文' and score > 50 then 1
                    end)
;

結果:

-- 1

STUDENT_ID SUBJECT1        SCORE
---------- ---------- ----------
       100 理化               80
       100 語文               80
       100 數學              100

-- 2

STUDENT_ID
----------
       100

內容多來自 《SQL進階教材》,僅做筆記。練習程式碼均為原創。

相關推薦

SQL——Having子句

執行環境 win10 / oracle(DB11g) 1、可以出勤的隊伍 思路: 一個集合中,如果元素最大值和最小值相等,那麼這個集合中肯定只用一種值 -- 創表 c

sql教程》之HAVING子句

本文是《sql進階教程》閱讀筆記,感興趣可以閱讀該書對應章節,這本適合有一定sql基礎的同學閱讀。另外作者《sql基礎教程》也值得一看 案例一、各隊,全體點名 查出現在可以出勤的隊伍。可以出勤即隊伍裡所有隊員都處於“待命”狀態 Teams mem

Linq To Sql系列(六)用object的動態查詢與保存log篇

directory ont 簡單 lambda表達式 bind add dbo 所有 生成 動態的生成sql語句,根據不同的條件構造不同的where字句,是拼接sql 字符串的好處。而Linq的推出,是為了彌補編程中的 Data != Object 的問題。我們又該如何實現

SQL17-變數的宣告/使用(輸出)--全域性變數/會話變數--使用者變數/區域性變數

/*進階17 變數 系統變數: 全域性變數: 會話變數: 自定義變數: 使用者變數: 區域性變數: */ /* #一: 系統變數 #說明: 變數由系統提供,不是使用者定義的,屬於伺服器層面 #使用的語法 #1/檢視所有的系統變數

SQL 教程

內容簡介 本書是《SQL 基礎教程》作者 MICK 為志在向中級進階的資料庫工程師編寫的一本 SQL 技能提升指南。 全書可分為兩部分,第一部分介紹了 SQL 語言不同尋常的使用技巧,帶領讀者從 SQL 常見技術,比如 CASE 表示式、自連線、HAVING 子句、外連線、關聯子查詢、EXIST

SQL(上)

CASE表示式 新手用WHERE字句進行條件分支,高手用SELECT字句進行條件分支 --男性人口 SELECT pref_name, SUM(population) FROM PopTbl2 WHERE sex='1' GROUP BY pref_nam

sql語句例項

1 多表查詢 通過where 將表進行關聯 表human,student資料如下圖: 將兩表通過id欄位進行連線 輸出 select t1.id,t1.name,t1.age,t1.sex,t2.chinese,t2.math,t2.english from hum

SQL練習題50道

表及資料 student SNO    SNAME    SAGE    SSEX 01    趙雷    1990-01-01 00:00:00    男 02    錢電    1990-12-21 00:00:00    男 03    孫風  

Oracle Insert增強與SQL

INSERT增強與SQL進階:一、同時向多張表中插入資料 語法: INSERT ALL INTO (表1) VALUES (查出來的欄位1, 查出來的欄位2) INTO (表2) VALUES (查出來

Oracle基礎(五)pl/sql(分頁過程)

   編寫分頁過程         通過pl/sql實現分頁過程,再該過程中由簡單到難一步步深入,目的在於通過該案例熟悉pl/sql的各種儲存過程,包,遊標,如何在java中呼叫等內容的學習。    1、無返回值的儲存過程      例如 1、可以向book表新增書,  

Oracle PL/SQL程式設計(第五彈:包的技術)

包過載 包過載實際上就是對包中的子程式的過載,之前我們已經對子程式的過載做過介紹,這裡簡單看下程式碼。 定義包規範: CREATE OR REPLACE PACKAGE emp_action_pkg_overload IS --定義一個增加新員工

Oracle PL/SQL

Oracle PL/SQL進階 控制結構 在任何計算機語言(c,java,c#,c++)都有各種控制語句(條件語句,迴圈語句,順序控制結構..)在pl/sql中也存在這樣的控制結構。 條件分支語句 pl/sql中提供了三種條件分支語句 if--then if--t

Oracle PL/SQL程式設計(第十五彈:動態SQL語句)

理解動態SQL語句 動態SQL語句基礎 動態SQL語句不僅是指SQL語句是動態拼接而成的,更主要的是SQL語句所使用的物件也是執行時期才建立的。出現這種功能跟PL/SQL本身的早起繫結特性有關,早PL/SQL中,所有的物件必須已經存在於資料庫中才能執行,

分享《SQL教程》高清中文PDF+原始碼

下載:https://pan.baidu.com/s/11-MnDu0khzwO4tiJqHznnA 《SQL進階教程》高清中文PDF+原始碼 下載:https://pan.baidu.com/s/1a-JepzWU77yH0IUfBiLPPw 《SQL基礎教程(第2版)》高清中文PDF+示例程式+習題

分享《SQL教程》高清中文PDF+源代碼

sts gbk 外連接 sql alt -m baidu 結合 tps 下載:https://pan.baidu.com/s/11-MnDu0khzwO4tiJqHznnA 《SQL進階教程》高清中文PDF+源代碼 下載:https://pan.baidu.com/s/1a

SQL知識點總結

一、CASE表示式(類似DECODE,IF) 1、兩種表示式 --簡單case表示式 case sex when '1' then '男' when '2'then '女' else '其它' end --搜尋case表示式 case when sex='1'then

sql教程》之幾個效能優化建議

本文是《sql進階教程》閱讀筆記,感興趣可以閱讀該書對應章節,這本適合有一定sql基礎的同學閱讀。另外作者《sql基礎教程》也值得一看 嚴格地優化查詢效能時,必須要了解所使用資料庫的功能特點。此外,查詢速度慢並不只是因為 SQL 語句本身,還可能是因為記憶體分配不佳、檔案結構

sql教程》之用 SQL 處理數列

本文是《sql進階教程》閱讀筆記,感興趣可以閱讀該書對應章節,這本適合有一定sql基礎的同學閱讀。另外作者《sql基礎教程》也值得一看 生成連續編號 在思考這道例題之前,請先思考下面一個問題: 00 ~ 99 的 100 個數中,0, 1, 2,…, 9 這 10 個

sql教程》之用 SQL 進行集合運算

本文是《sql進階教程》閱讀筆記,感興趣可以閱讀該書對應章節,這本適合有一定sql基礎的同學閱讀。另外作者《sql基礎教程》也值得一看 集合運算的幾個注意事項 UNION ALL 和UNION的區別除了運算結果以外,這兩種用法還有一個不同。集合運算子為了排除掉重複行,預設地會發生

SQL必知必會(第4版)》中英文PDF及程式碼+《SQL教程》中文PDF及程式碼 (學習總結)

下載:https://pan.baidu.com/s/1hRb-TS_R-0fnXPodS5OoDg 《SQL必知必會(第4版)》高清中文PDF+高清英文PDF+程式碼 下載:https://pan.baidu.com/s/11-MnDu0khzwO4tiJqHznnA 《SQL進階教程》高清中文PDF