如何在SAS中禁用内部排序?

时间:2016-12-13 10:59:59

标签: loops variables macros sas

假设我有一个带有两列的管道分隔文本文件:

LIBRARY_NAME|TABLE_NAME
A.|ZZZ
A.|XXX
B.|QQQ
B.|AAA
B.|MNO
B.|OPQ

我使用INFILE语句导入文件,并将两列的所有值分别分配给宏变量& LIB和& TAB。

/* COUNT THE TABLES IN ORDER TO BE ABLE TO LOOP THROUGH THEM LATER: */
PROC SQL;

    SELECT COUNT(*) INTO :TABLE_C FROM TABLE_NAMES; 
    /* DELETE LEADING BLANKS FROM THE COUNT: */
    %LET TABLE_COUNT = &TABLE_C; 

QUIT;


/* MAKE A LIST OF THE LIBRARY & TABLE NAMES: */
PROC SQL NOPRINT;

    SELECT 
        LIBRARY_NAME

        INTO 
            :LIB1 - :LIB&TABLE_COUNT

        FROM 
            WORK.TABLE_NAMES;

    SELECT 
        DISTINCT TABLE_NAME

        INTO 
            :TAB1 - :TAB&TABLE_COUNT

        FROM 
            WORK.TABLE_NAMES;

QUIT;

所以从本质上讲,我现在有两个"阵列"包含所有库和表。 现在我想在宏中进行DO LOOP,转到相关的库和表,检索相关数据并在WORK库中创建相关表:

%DO N = 1 %TO &COUNT;

    PROC SQL;

        CREATE TABLE WORK.&&TAB&N AS 

            SELECT
                *

                FROM
                    &&LIB&N.&&TAB&N

                WHERE
                    AGE > 50;

    QUIT;

%END;

问题是,它只创建了一些表。我得到这个错误,表A.AAA和A.MNO表不存在。这是真的。所以,不知何故,SAS正在混合这两列或它们的顺序。它不是按照它们在源文件中出现的顺序进行循环,而是将正确的库与右表组合在一起,而是以某种方式混合它。 编辑:我现在非常确定SAS会对这两种阵列进行排序"阵列"在DO LOOP之前自动显示库和表名,这对我来说是非常好的,因为它混合了所有。 如何强制SAS不自动对值进行排序,以便保留两列的原始顺序? EDIT2:当我更改源文本文件中库的顺序(即将B表放在A表前面)时,它可以正常工作。真奇怪。

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:3)

您可以跳过PROC SQL代码。只需在读取源文件时生成宏变量。

data table_names ;
  infile 'myfile' dsd dlm='|' firstobs=2 truncover ;
  length library_name $9 table_name $32 ;
  input library_name table_name ;
  call symputx(cats('LIB',_n_),library_name);
  call symputx(cats('TAB',_n_),table_name);
run;

答案 1 :(得分:2)

DISTINCT是您订购数据的原因。 SQL不能确定什么是唯一的,没有某种类型。 您也不需要提前知道项目数,SAS默认会创建足够的宏变量。 您可以通过创建单个宏变量列表来避免这种情况。

 Proc SQL noprint;
     Select distinct catx('.', library_name, table_name) into :ref_list1-
 From work.table_names;
 Quit;

%put &ref_list1;