Search code examples
selectsaswhere-clauseproc-sqlselect-into

T:SAS/ Proc SQL - select into: not in:


I currently have a proc contents datafile which looks like this:

DATA CONTENTS;
    INPUT NAME $;
    DATALINES;
        VARA
        VARB
        VARC
        VARD
        VARE
    ;
RUN;

and I'm looking to turn this last of variables into a macro variable like so

PROC SQL;
    SELECT NAME INTO: MACRO_VARIABLE
        SEPARATED BY " "
            FROM CONTENTS
                WHERE VARNUM > 1
                AND
                WHERE NAME NOT IN:(VARA VARB)
;
QUIT;

The new addition which I'm trying to fit is the

Where name not in:(VarA varB)

is there a way to do this as my VARA and VARB are user inputs from my controller page, I can't specify them to be comma delimited as they will be "group_by" variables later in the script.

EDIT:

Imagine I have a macro variable in my controller

%LET group_by_variable = VARA VARB;

Then I do the same routine but substitute the macro variable like so

PROC SQL;
SELECT NAME INTO: MACRO_VARIABLE
    SEPARATED BY " "
        FROM CONTENTS
            WHERE VARNUM > 1
            AND
            WHERE NAME NOT IN:(&group_by_variable.)
 ;
QUIT;

Solution

  • In regular SAS statements you can use the colon modifier to do truncated string operations.

    if  NAME NOT IN: ('VARA' 'VARB')
    

    But in PROC SQL (and also WHERE statements) you cannot. So use the EQT operator instead.

    WHERE NAME NOT EQT 'VARA'
    

    You cannot use variables names with the IN operator. But it looks like you do not mean to reference variable names, but actual character strings. So you need to add quotes around the values.

    It is not hard to add quotes around a space delimited list. You can do it with one function call if there is exactly one space between the values.

    "%sysfunc(tranwrd(VARA VARB,%str( )," "))"
    

    If your list of names is in a macro variable then use compbl() to make sure there is one space only.

    %let mylist=%sysfunc(compbl(&mylist));