inline sql query error - sas

I am writing this basic sql statement in proc sql yet SAS throws me an error.
proc sql;
select interest from
(select * from project.data_model
order by ethnicity desc, satscore desc);
quit;
ERROR 79-322: Expecting a ).
ERROR 22-322: Syntax error, expecting one of the following: ;, ','.
ERROR 200-322: The symbol is not recognized and will be ignored
I know I can write interest in the inner query itself but I was just giving a try using inline query.
Please help.

The error message you receive is not very helpful. The problem you have is that order by is not valid within an in-line view, which is effectively what your subquery is creating. To solve this you need to put the order by statement outside of the subquery.
proc sql;
select interest from
(select * from project.data_model)
order by ethnicity desc, satscore desc;
quit;

Related

SAS: Variable list contains names with '-' symbol, resulting in error during keep= statement

I have SAS datasets with multiple variables like H9999-999-999-999. However, I need to drop the unnecessary columns and am using a variable list(ParamList) to do that:
proc sql;
select _NAME_ into :ParamList separated by ' '
from uniquePlanList;
quit;
%put ParamList = &ParamList.;
proc sql;
create table test as
select * from out.seq_summ(keep=BPT_Cat &ParamList.);
run;
Because my variables contain '-' symbols I receive the following errors:
ERROR 214-322: Variable name - is not valid.
ERROR 214-322: Variable name 000 is not valid.
ERROR 80-322: Expecting a variable name.
ERROR: Invalid value for the KEEP option.
ERROR: Invalid option name -000.
ERROR: Some options for file OUT.SEQ_SUMM were not processed because of errors or warnings noted above.
I know if I were to list out the variables like this:
(keep=BPT_Cat 'H9999-999-999-999'n 'H9999-999-999-998'n)
Then the code would work. But I have some datasets with hundreds of variables. Is there a better way to drop the unnecessary columns than using a variable list? Or is there some clever way to read in the variable list as a string?
I tried using this:
(keep=BPT_Cat %str(&ParamList.)) but that gave me the same errors as above.
Use the NLITERAL() function to generate names in a form that you can use in code.
proc sql noprint;
select nliteral(_NAME_)
into :ParamList separated by ' '
from uniquePlanList
;
quit;
how about:
proc sql;
select quote(_NAME_)||"n" into :ParamList separated by ' '
from uniquePlanList;
quit;
%put ParamList = &ParamList.;
proc sql;
create table test as
select * from out.seq_summ(keep=BPT_Cat &ParamList.);
run;
Don't have SAS with me at the moment can't really test it.

ERROR: Attribute '2017-02-28' not found

I have the following query which runs in SAS using proc sql where I have an automated variable which contains the month end date but it results in the following error
ERROR: Prepare error: ICommandPrepare::Prepare failed. : ERROR: Attribute '2017-02-28' not found
Query:
proc sql;
connect to oledb (datasource='10.1.0.105' provider=nzoledb
user=&user_id password=&pwd properties=('initial catalog'=ODS));
create table &user..Pers_test as select * from connection to oledb
(SELECT a.ID from DBO.Table1
where a.SOURCE_SYSTEM_CREATED_DTM <= "&monthend."
Group by a.SWID order by a.SWID
);
%let _sql_xrc=&sqlxrc;
disconnect from oledb;
quit;
However the query runs when the timestamp is hardcoded.
proc sql;
connect to oledb (datasource='10.1.0.105' provider=nzoledb
user=&user_id password=&pwd properties=('initial catalog'=ODS));
create table &user..Pers_test as select * from connection to oledb
(SELECT a.ID from DBO.Table1
where a.SOURCE_SYSTEM_CREATED_DTM <= '2017-02-28 00:00:00'
Group by a.SWID order by a.SWID
);
%let _sql_xrc=&sqlxrc;
disconnect from oledb;
quit;
I have tried casting, substring but it all results in the same error. Any help is appreciated to work around with the automated variable.
The variable was not getting resolved under single quotes and hence double quotes was being used. But being double quotes, the column could not identify with the value and the error got thrown up. So, the variable had to be resolved under single quotes.
The code to resolve the variable under single quote is as follows
cast(%unquote(%str(%')&monthend.%str(%')) as datetime)
I modified Karan Pappala's answer to make it work for me:
%unquote(%str(%')&execution_method.%str(%'))

Comparing two date variables in SAS in a proc sql WHERE clause

I am using SAS Enterprise guide and want to compare two date variables:
My code looks as follows:
proc sql;
CREATE TABLE observations_last_month AS
SELECT del_flag_1,
gross_exposure_fx,
reporting_date format=date7.,
max(reporting_date) AS max_date format=date7.
FROM &dataIn.
WHERE reporting_date = max_date;
quit;
If I run my code without the WHEREstatement I get the following data:
However, when I run the above code I get the following error messages:
ERROR: Expression using (=) has components that are of different data types.
ERROR: The following tables were not found in the contributing tables: max_date.
What am I doing wrong here? Thanks up front for the help
If you want to subset based on an aggregate function then you need to use HAVING instead of WHERE. If you want to refer to a variable that you have derived in your query then you need to use the CALCULATED keyword (or just re-calculate it).
proc sql;
CREATE TABLE observations_last_month AS
SELECT del_flag_1
, gross_exposure_fx
, reporting_date format=date7.
, max(reporting_date) AS max_date format=date7.
FROM &dataIn.
HAVING reporting_date = CALCULATED max_date
;
quit;

Using date macro variable in PROC SQL

I am having trouble getting a macro variable to work correctly in PROC SQL and it doesn't make sense to me.
First, if I generate a query like this:
PROC SQL;
SELECT
a.*
,'31MAR2016' As EVAL_DATE format=date09.
FROM
myTable a
;
it works as expected and puts a date field at the end of the table.
Then, if I do this:
%Let testDate = '31MAR2016'd;
%put &testDate;
PROC SQL;
SELECT
a.*
,&testDate As EVAL_DATE format=date09.
FROM
myTable a
;
this again runs properly, with the log window showing the value of:
'31MAR2016'd
But, if I do this:
%Let Eval_Date = %sysfunc(intnx (month,%sysfunc(inputn(201603,yymmn6.)) ,0,E),date09.);
%Let Eval_date_test = %str(%')&Eval_Date.%str(%')d;
%Put Eval_date_test;
PROC SQL;
SELECT
a.*
,&Eval_date_test As EVAL_DATE format=date09.
FROM
myTable a
;
SAS stops running with the error;
"ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant,
a missing value, (, *, +, -, BTRIM, CALCULATED, CASE, EXISTS, INPUT, NOT, PUT, SUBSTRING, TRANSLATE, USER, ^, ~.
ERROR 200-322: The symbol is not recognized and will be ignored."
The log displays the value of &Eval_date_test to be the same '31MAR2016'd as it was in the second example. Note that I created the variable in two steps for clarity, but the same thing happens if you create it in one step.
In case it matters, I am running SAS Enterprise Guide 6.1
Why doesn't this work?
This has to do with how the macro is being dereferenced with the %str() macro. Try the %unquote() macro:
PROC SQL;
SELECT
a.*
, %unquote(&Eval_date_test) As EVAL_DATE format=date09.
FROM
sashelp.cars a
;
quit;
http://support.sas.com/documentation/cdl/en/mcrolref/67912/HTML/default/viewer.htm#p1f5qisx8mv9ygn1dikmgba1lmmu.htm
You are working much too hard and just confusing poor old SAS. Instead of using macro quoting just use the right quote characters to begin with. SAS doesn't care which quote characters you use, but text inside of single quotes is not evaluated for macro triggers and text inside of double quotes is. So '&eval_date'd does not resolve the macro variable reference and "&eval_date"d does.
%let Eval_Date="%sysfunc(intnx(month,%sysfunc(inputn(201603,yymmn6)),0,E),date9)"d;
You're missing a comma after a.*

Proc sql VALIDATE with CREATE TABLE

I am working in SAS EG and I have code like this:
proc sql;
CREATE TABLE new as
SELECT f1,f2
FROM work.orig
WHERE f1<>'x'
;
This works.
However, when I add a VALIDATE option, like below, I get an error:
ERROR 22-322: Syntax error, expecting one of the following: (, SELECT.
ERROR 202-322: The option or parameter is not recognized and will be ignored.
proc sql;
CREATE TABLE new as
VALIDATE
SELECT f1,f2
FROM work.orig
WHERE f1<>'x'
;
How do I use the validate option in proc sql?
My understanding is that you cannot use the VALIDATE with the CREATE statement.
Validate the underlying SELECT
proc sql;
VALIDATE
SELECT f1,f2
FROM work.orig
WHERE f1<>'x'
;
quit;
If that is successful, then your CREATE statement will work.