SQL常用語句(面試必備)

SQL概念和標準SQL語言
  • SQL英文全稱是Structured Query Language,即結構化查詢語言
  • SQL是關係數據庫操作的國際標準語言

在這裏插入圖片描述

SQL的功能
  • 產生彙總統計表
  • 從表和視圖中檢索數據
  • 合併表和視圖中的數據
  • 建立表、視圖和索引
  • 修改、添加、提出表中的數據列
  • 更新表中的數據值
SQL過程舉例
Proc sql;/*開始SQL過程*/

  create table  test as  /*創建表*/

  select  a.comcd, a.lcomchnm, b.stkcd, b.lstknm,         a.csrciccd1, count(a.comcd) as n
  from resdat.cinfo a left join resdat.lstkinfo b 
  on  a. stkcd=b.stkcd
  where  estdt>'1jan1985'd
  group by a.csrciccd1
  order by a.csrciccd1; /*查詢語句*/
  quit;/*終止SQL過程*/  

一、查詢語句

  • SELECT語句是PROC SQL的最主要、最常用的工具。
  • 用來識別、檢索和操作表中數據,使用子句可以設定查詢條件。
  • 常用子句及其固定順序:
    • Select 選擇的變量/列名
    • from 來源數據集/表名
    • where 選擇條件
    • group by 分組標誌(變量)
    • having 針對組的選擇條件
    • order by 排序標誌(變量)
  • 其中只有select和from是必須的,其他子句都是可選的
1. SELECT子句
選擇列
  • 特定列:select+列名

  • 多個列名用 “,” 分隔;按照語句中順序顯示列

  • 所有列:select *

  • 刪除重複觀測: select distinct+列名

  • 如果有多個列,只刪除所有變量取值都相同的觀測

計算新列值; 爲列分配別名; 指定列屬性;
引用新計算的列:calculated +列名,只能在select和where子句中設定calculated列。
Proc sql;
    select  name, age, height from resdat.class;
    select  *  from resdat.class;
    select  distinct  age from resdat.class;
Quit;

Proc sql;
   select name, weight/height as whratio format=4.2 
from resdat.class;
Quit;

Proc sql;
   select name, age, weight/height as whratio format 4.2, 
         (1/calculated whratio) as hwratio format 6.4
   from resdat.class;
Quit;
2. WHERE子句

選擇條件:where + 條件表達式

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-H61C0J8E-1585755384561)(C:\Users\SHERRY~1\AppData\Local\Temp\1585671275638.png)]

  • 比較算符和邏輯算符還有一些等價形式。
  • 所有算符前面加一個not算符,可以得到相反的選擇條件。
  • 條件較複雜時,可以將表達式用括號括起來,以突出邏輯關係、增強可讀性。
幾個重要條件算符
  • in: 符合選項之一; in+(選項1,選項2,…)
  • between-and: 選擇一定範圍
  • like:部分或全部匹配; %可代替任意數量的字符; _可代替一個字符
proc sql;
   select * from resdat.class where age in (12 14 16);
   select * from resdat.class where age between 12 and 15;
   select * from resdat.class where (sex='F' and weight>100) or (sex='M' and weight<=90);
   select * from resdat.class where name like '%h%';
   select * from resdat.class where name like '_h%';
 quit;
3. GROUP BY和ORDER BY子句
  • Group by一般與彙總函數結合使用,彙總函數按照GROUP BY子句進行分組彙總:
    • 如果沒有GROUP BY,就默認整個表爲一組;
    • 如果沒有彙總函數,則GROUP BY單純分組。
  • Order by對結果排序
proc sql;
 select name, sex, count(sex) as n, avg(height) as avgh 
 from resdat.class
 group by sex
 order by name desc;
quit;

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vdeSWYDw-1585755384562)(C:\Users\SHERRY~1\AppData\Local\Temp\1585671521818.png)]

4. HAVING子句

HAVING篩選組數據

  • HAVING對組設定條件,進行檢索篩選;
  • 在GROUP BY和彙總函數後運行,可以引用匯總函數結果。

與WHERE子句的區別:

  • WHERE對觀測設定條件,進行檢索篩選;
  • 在GROUP BY和彙總函數前運行,不可以引用匯總函數結果。
proc sql;
 select age, avg(height) as avgh 
 from resdat.class
 group by age
 having avgh>60;
quit;
SELECT語句綜合練習

選擇resdat.class中,名字首字母不是 B 的學生數據。

  • 按年齡分組統計平均體重(avgw)、每組人數(n)
  • 輸出平均體重大於100的組,列示年齡、平均體重、每組人數
  • 按照年齡倒序排列
proc sql;
 select age, avg(weight) as avgw, count(*) as n 
 from resdat.class
 where name not like 'B%'
 group by age
 having avgw>100
 order by age desc;
quit;

二、多表查詢

  • FROM後面直接加一個表名,實現從單個表中檢索數據涉及多個表,常使用連接或子查詢。
  • 連接查詢: 從多個表中選取數據 數據來自不同的表
  • 子查詢: 通過表與表之間的聯繫選取數據 選擇一個表的數據時, 需要參照其他表的信息。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Za5EVZRI-1585755384562)(C:\Users\SHERRY~1\AppData\Local\Temp\1585753642715.png)]

1. JOIN連接——交叉連接

交叉連接(CROSS JOIN)/簡單連接 (,):

最基本的連接,笛卡爾積形式,所有可能組合。

proc sql;
  select * from resdat.china cross join resdat.usa;
  select * from resdat.china , resdat.usa;
quit;

如果觀測行數很多,這種連接會產生巨大的數據結果,且絕大部分沒有意義,可用其他JOIN連接選擇相應子集。

JOIN連接——內部連接
  • 返回兩表中匹配連接條件的行:表a inner join 表b on 連接條件
    • 查詢時經常遇到兩個表有相同列,爲了引用清楚,在列前加表名;
    • 爲了書寫和閱讀方便,可在from子句中設定表的別名;
    • 關鍵詞inner, as可選;
    • 仍然可以使用where、order by等子句。
例:
proc sql;
  select * from resdat.china as a inner join resdat.usa as b 
  on a.level=b.level;
quit;

等價於:
proc sql;
  select * from resdat.china a , resdat.usa b 
  where a.level=b.level;
quit;
JOIN連接——外部連接
  • 返回內部連接的行以及部分不匹配連接條件的行;
    • 左外部連接(LEFT JOIN):內部連接行+左邊表中不符合匹配條件的行;
    • 右外部連接(RIGHT JOIN):內部連接行+右邊表中不符合匹配條件的行;
    • 完全外部連接(FULL JOIN):內部連接行+左右兩表中不符合匹配條件的行。
例:
proc sql;
 select * from resdat.china a left join resdat.usa b on a.level=b.level;
 select * from resdat.china a right join resdat.usa b on a.level=b.level;
 select * from resdat.china a full join resdat.usa b on a.level=b.level;
quit;
JOIN連接和MERGE語句比較
  • DATA中的MERGE和SQL過程中的JOIN語句

    在很多情況下可以產生相同結果:

    • 所有行匹配且無重複值情況:merge=inner join
    • 部分行匹配且無重複值情況:merge=full join
  • 區別在於:

    • 有重複值的情況:merge按照位置順序合併;join根據具體值連接,可以產 生所有組合,並可以選擇其子集;
    • JOIN連接之前不需要排序;
    • JOIN可以進行不等值連接
  • 所以總的來說,JOIN比MERGE更靈活。

JOIN連接綜合練習
按照level相同的原則匹配中美兩隊隊員,分別選擇:
中國隊所有隊員的匹配情況;美國隊所有隊員的匹配情況;
中美兩隊成功匹配的隊員;中美兩隊所有隊員的匹配情況

參考程序:
proc sql;
 select * from resdat.china a left join resdat.usa b on a.level=b.level;
 select * from resdat.china a right join resdat.usa b on a.level=b.level;
 select * from resdat.china a inner join resdat.usa b on a.level=b.level;
 select * from resdat.china a full join resdat.usa b on a.level=b.level;
quit;

思考分別如何實現:美國隊內部按照level相同原則匹配?
按照美國隊員比中國隊員level低的原則匹配?
proc sql;
 select * from resdat.usa a left join resdat.usa b on a.level=b.level;
 select * from resdat.china a left join resdat.usa b on a.level>b.level;
quit;
2. 子查詢

子查詢——簡單子查詢

在一個查詢語句中,用到了另一個查詢的結果

  • 簡單子查詢(不相關子查詢):
  • 子查詢獨立於外部查詢;
  • 子查詢返回的結果要與該查詢外的算符相對應:
    • 如果是比較算符如>、=等,子查詢只能返回一個值;
    • 如果是條件算符如in、any、all等,子查詢可以返回多個值。
proc sql;
 select * from resdat.usa 
   where level<(select max(level) from resdat.china);
 select * from resdat.usa 
   where level in (select distinct level from resdat.china);
quit;
子查詢——混合子查詢

混合子查詢:子查詢用到外部查詢傳輸進來的值,該子查詢運行後再給外部查詢返回結果;可以返回單值或多值。

  • 其實子查詢可以拆分成兩個單獨的查詢,學習創建表之後可以實現
proc sql;
 select * from resdat.yrret a
 where (select stktype from resdat.lstkinfo b 
        where a.stkcd=b.stkcd)='A'
    and '01jan2005'd<=date<='31dec2005'd;
quit;
合併查詢(SET算符)
  • 合併查詢:對兩個完全匹配的查詢結果進行並、差、交運算與JOIN的橫向連接不同,SET算符是豎直的連接。

    select 語句1 + SET算符 + select 語句2

  • UNION:產生多個查詢中所有的非重複觀測

  • EXCEPT:產生只屬於第一個查詢、不屬於第二個查詢的觀測

  • INTERSECT:產生兩個查詢共同的觀測

  • OUTER UNION:對多個查詢結果直接連接

三、創建與更新表

  • 創建表:CREATE TABLE + 表名
  • 列定義方式: CREATE TABLE + 表名+(列名、類型、長度、格式、標籤)
  • 從查詢結果創建表: CREATE TABLE + 表名 + AS + SELECT語句
    • 新表包括SELECT語句所選擇的列,且保持原來的列屬性
proc sql;
 create table class 
   (code char(6), name char(20), 
    date num informat=date9. format=data9.);
quit;

proc sql;
 create table resdat.class1 as select * from resdat.class;
quit;

利用表過渡,將子查詢拆分成兩個查詢

例:
proc sql;
 select * from resdat.usa 
   where level in (select distinct level from resdat.china);
quit;

拆分:
proc sql;
 create table a as select distinct level from resdat.china;
 create table b as select * from resdat.usa a join a b
   on a.level=b.level;
quit;

使用DATA SET選項:在from語句中的表名後,可以使用DATA SET選項語句。

  • 在表中插入行: insert into+表名
  • 用SET子句插入行:insert into+表名+ set + 根據列名賦值
  • 用VALUES子句插入行: insert into+表名+ VALUES +(對應列的位置賦值)
proc sql;
 insert into resdat.class1  set name='Lily', age1=13, sex='F', height=60.5;
 insert into resdat.class1  values ('Lucy', 'F', 14, ., 89);
 select * from resdat.class1;
quit;

還可以對錶進行以下操作:更新觀測、刪除觀測;增加列、修改列、刪除列;刪除表 等等。

  • 在這些功能上,PROC SQL與DATA步相比,沒什麼優勢,因此不做贅述
  • PROC SQL還包括視圖功能:
    • 對視圖(Views)的各種操作與表(Table)基本相同
    • 差別在於:
      • 視圖不儲存數據,只是儲存一個查詢語句;
      • 在使用該視圖時調用該查詢並展現結果。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章