小言_互联网的博客

SQL常用语句(面试必备)

383人阅读  评论(0)
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 + 条件表达式

  • 比较算符和逻辑算符还有一些等价形式。
  • 所有算符前面加一个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;

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后面直接加一个表名,实现从单个表中检索数据涉及多个表,常使用连接或子查询。
  • 连接查询: 从多个表中选取数据 数据来自不同的表
  • 子查询: 通过表与表之间的联系选取数据 选择一个表的数据时, 需要参照其他表的信息。

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)基本相同
    • 差别在于:
      • 视图不储存数据,只是储存一个查询语句;
      • 在使用该视图时调用该查询并展现结果。

转载:https://blog.csdn.net/weixin_45926367/article/details/105258966
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场