SAS:如何在proc sql WHERE语句中迭代数据集元素?

时间:2015-01-07 21:55:31

标签: sas

我需要使用proc sql

创建多个表格
   proc sql;

   /* first city */
   create table London as 
   select * from connection to myDatabase 
   (select * from mainTable 
    where city = 'London'); 

   /* second city */
   create table Beijing as 
   select * from connection to myDatabase 
   (select * from mainTable 
    where city = 'Beijing');

   /* . .  the same thing for other cities */

   quit; 

这些城市的名称位于sas表myCities

如何将data步骤嵌入proc sql以迭代所有城市?

4 个答案:

答案 0 :(得分:2)

proc sql noprint;
select quote(city_varname) into :cities separated by ',' from myCities;
quit; 

*上面的这一步创建了一个列表,作为与下面的in()运算符一起使用的宏变量。编辑:Per Joe的评论,添加quote()函数,以便每个城市将进入引号内的宏变量列表,以便通过下面的in()运算符进行正确的引用。

create table all_cities as 
select * from connection to myDatabase 
(select * from mainTable 
where city in (&cities));

*此步骤只是您在问题中提供的步骤,略微修改为在()中使用上面定义的宏变量列表。

答案 1 :(得分:1)

  1. 您需要将proc sql代码放入SAS宏中。
  2. 为City创建一个宏变量(在我的例子中,我称之为宏变量" City")。
  3. 从datastep程序执行宏。由于Datastep程序为每个观察处理一个,因此不需要创建复杂的逻辑来迭代。

    data mycities;
        infile datalines dsd;
        input macrocity $ 32.;
        datalines;
    London
    Beijing
    Buenos_Aires
    ;
    run;
    
    %macro createtablecity(city=);
    proc sql;
       /* all cities  */
       create table &city. as 
       select * from connection to myDatabase 
       (select * from mainTable 
        where city = "&city.");
    quit; 
    %mend;
    
    data _null_;
        set mycities;
        city = macrocity;
        call execute('%createtablecity('||city||')');
    run;
    

答案 2 :(得分:1)

一个相对简单的解决方案是在数据步骤中完全执行此操作。假设您可以通过libname连接(如果您可以通过connect to连接,则可能),假设libname为mydb。在第一部分中使用与Max Power相似的结构:

proc sql noprint;
  select city_varname 
    into :citylist separated by ' ' 
    from myCities;
  select cats('%when(var=',city_varname,')') 
    into :whenlist separated by ' '
    from myCities;
quit; 

%macro when(var=);
  when "&var." output &var.;
%mend when;


data &citylist.;
  set mydb.mainTable;
  select(city);
    &whenlist.;
    otherwise;
  end;
run;

如果您正在使用mainTable中的大部分数据,这可能不会比在数据库端使用数据慢得多,因为您无论如何都在移动所有数据 - 并且可能会因为您只有更快的速度点击数据库一次。

更好的方法是将其拉到一个表格(如Max节目),但如果你需要创建多个表格,这是一个合理的方法。

答案 3 :(得分:1)

与其他解决方案类似,可能更简单一点......拉出一个不同的城市列表,放入宏,在do循环中运行SQL查询。

Proc sql noprint;
  Select distinct city, count(city) as c
  Into :n1-:n999, :c
  From connection to mydb
  (Select *
   From mainTable)
;
 Quit;

%macro createTables;

%do a=1 %to &c;

Proc sql;
  Create table &&n&a as
  Select  *
  From connection to myDb
  (Select *
   From mainTable
   Where city="&&n&a")
;
 Quit;

%end;

%mend createTables;

%createTables;