9.创建索引

创建索引时,索引的名字必须与表中所建索引的列名相同。另外,当索引唯一时,加入关键字unique。可以在多个列上创建复合索引(composite index)。

创建索引格式如下

CREATE <UNIQUE> INDEX index-name ON table-name(column-name,  column-name);

注:(1)可以基于数值型或字符型列创建索引。

(2)在同一个列名上不必创建两个索引。

(3)若预先对要创建索引的表排序,可提高索引的性能。

(4)复合索引名不能与列名相同。

下述例子创建了基于EmpID的索引,并且不允许有重复ID。

Proc sql;  
Create unique index EmpID  
On airline.payrollmaster(EmpID);

创建复合索引:

proc sql;  
create unique index daily  
on airline.marchflights(FlightNumber, Date);

10.修改表

使用Proc SQL 能够

(1) 修改数据值

(2) 增加行到一个表或视图

(3) 删除行

(4) 修改表的列属性

(5) 增加新列到一个表

(6) 删除列

(7) 删除整个表,视图或索引

(1)更新数据值

UPDATE table-name  
SET column-name=expression,  
SET column-name=expression,  
Where expression;

例如

proc sql;  
update sirline.payrollmaster  
set Salary=Salary*  
Case when substr(JobCode,3,1)= ’ 1’ then 1.05  
When substr(jobCode,3,1)= ’ 2 ’ then 1.10  
When substr(JobCode,3,1)= ’ 3’ then 1.15  
Else 1.08  
End;

(2)插入数据到表或视图

INSERT INTO table-name  
SET column-name=value,…  
INSERT INTO table-name <(column list)>  
VALUE (value,value,…);  
INSERT INTO table-name<(column list)>  
SELECT columns from table-name

(3)删除行

DELETE RROM table-name  
WHERE expression;

(4)修改列

一般形式如下:

ALTER TABLE table-name  
ADD column-definition, column-definition,…  
DROP column-name, column-name,…  
MODEIFY column-definition, column-definition, …

例1.增加列

proc sql;  
alter table airline.payrollmaster  
add Bonus num format=comma10.2  
Level char(3);

例2.删除列

proc sql;  
alter table airline.payrollmaster  
drop DestinationType;

例3.修改列的属性

proc sql;  
alter table airline.payrollmaster  
modify Bonus num format=comma8.2,  
Level char(1)  
Label=’ Employee Level’;

(5) 删除表,索引和视图

一般形式如下:

DROP TABLE table-name, table-name,…;  
DROP VIEW view-name, view-name,…;  
DROP INDEX index-name, index-name, …  
From table-name;

更新视图的例子:

创建视图:proc sql;

create view airline.raise as  
select EmpID, JobCode, Salary, Salary/12 as MonthlySalary format=dollar12.  
From airline.payrollmaster;

更新视图

proc slq;  
update airline.raise  
set Salary=Salary*1.20  
where JobCode=’ PT3’;

11.Proc SQL 与宏

一个简单的将宏嵌入Proc SQL的例子如下:

%let datasetname=payrollmaster;  
%let bigsalary=100000;  
select *  
from airline.&datasetname  
where Salary>&bigsalary;

等价于

select *  
from airline.payrollmaster  
where Salary>100000;

Proc SQL能够使用INTO子句创建或更新宏变量。使用形式有3种:

方法1 在elect表达式中使用into关键字

SELECT col1, col2, …

INTO : mvar1, :mvar2,…

FROM …

注意:此种方式仅对宏变量赋给查询结果的的第一行的值。

例如,下述例子将雇员的平均值赋给一个宏变量后,再查询出薪水大于平均值的雇员。

%let code=NA1;  
select avg(Salary) into :mean  
from airline.payrollmaster  
where JobCode=’ &code’;  
reset print;  
title1 “&code Employee Earning Above-Average Salaries”;  
title2 “Average Salary for &code Employees Is &mean”;  
select *  
from airline.payrollmaster  
where Salary>&mean and  
JobCode=”&code”;

方法2 将查询结果的前n个结果赋给n个宏变量

SELECT a,b,…

INTO :a1- :an, :b1- :bn

FROM …

例如,按类统计有多少个飞行员

reset noprint;  
select MemberType, count(*) as Frequency  
into :memtype1-:memtype3,  
:freq1-:freq3  
from airline.frequentflyers  
group by MemberType;  
%put Member types: &memtype1 &memtype2 &memtype3;  
%put Frequencies: &freq1 &freq2 &freq3;

方法3 将所有查询结果,以分隔符分隔开,赋给某个宏变量

其形式为

SELECT col1,col2, …

INTO :macrovar1, :macrovar2, …

SEPARATED BY ’ delimiter’

FROM…

例如

select distinct Destination  
into :airportcodes  
separated by ’ ’  
from airline.internationalflights;  
%put &airportcodes;

系统宏变量有

SQLOBS 记录输出或删除的行数

SQLRC 保留每条SQL语句返回的代码

SQLOOPS 保留SQL语句中循环的次数

例如,写一条宏,将州代号作为参量,创建一个保留此洲的雇员的表,显示此表的前10条记录。

%macro state(st);  
proc sql;  
create table &st as  
select LastName, FirstName  
from airline.staffmaster  
where State=”&st”;  
%put NOTE: The table &st has &sqlobs rows. ;  
title “&st Employee”;  
%if &sqlobs>10 %then %do;  
%put NOTE: only the first 10 rows are displayed;  
title2 “NOTE : only 10 rows are displayed. “  
reset outobs=10;  
%end;  
select * from &st;  
quit;  
%mend state;

调用宏:

%state(NY)

12 程序测试与性能

PROC SQL的参数设置可以测试SQL程序,评价其性能。

EXEC|NOEXEC 控制所提交的SQL是否执行。

NOSTIMER|STIMER 在SAS LOG中报告对每和SQL性能的统计

NOERRORSTOP|ERRORSTOP 错误发生后,PROC SQL进入语法检查模式。

例如下述语句显示SELECT *中所缩写的列名,但并不执行其查询。

%let datasetname=payrollmaster;  
proc sql  
feedback  
noexec;  
select *  
from airline.&datasetname ;