I am trying to use a variable on PROC SQL but i cannot find a proper way through the internet. I just want to apply the following code of T-SQL on PROC SQL:
declare #example as int;
set #example=2;
select * from {table} where {column}=#example;
go
How can i apply this code on PROC SQL?
The translation to SAS SQL is to use a macro variable, the code looks pretty similar, need to wrap it in a PROC SQL block though.
%let example=2;
proc sql;
select *
from table
where variable=&example;
quit;
EDIT: my original reference to the macro variable was incorrect, use an ampersand in SAS not # symbol.
Related
I'm looking to create a macro variable. The macro variable name needs to be made by concatenating text to an already existing variable after it has resolved. Specifically, I want to do this in a PROC SQL block using INTO:. Here's a snippet to explain what I want to do.
%macro MyMacro(process);
PROC SQL;
SELECT
COUNT(*) INTO: &process._new_text
FROM
DataSetHere
;QUIT;
%mend MyMacro;
If I call on this macro and I pass the word "cat" into process, I want to have now declared/initialized a variable with the name cat_new_text, and it should return the COUNT(*) selected in that query whenever &cat_new_text is referenced.
I've done a little reading around, looked into using multiple ampersands, trying to resolved &process within quotes first - nothing has really solved my exact problem. Does anyone know of a clear cut way to accomplish this?
Thanks in advance!
Your code seems fine and it seems like it would do exactly what you describe.
However if your trying to "access" that new macro variable outside the macro, e.g.,
%MyMacro(cat);
%put &cat._new_text.;
then indeed it will not work because the variable was created locally in your macro and does not exist outside the scope of that macro.
To fix that, you simply need to add a %global statement in your macro definition:
%macro MyMacro(process);
%global &process._new_text;
PROC SQL;
SELECT COUNT(*)
INTO: &process._new_text
FROM DataSetHere
;
QUIT;
%mend MyMacro;
I have 12 columns and I want to add them through sql. I have tried:
proc sql;
select*,sum(a1-a12) as total
from tablename;
quit;
However this isn't working. Is there an alternative or can we use single and double hash only in Data steps.
If you want to add values in the same observation then you need to use SAS function sum(,...) and not the SQL aggregate function sum(). You current code looks like the later since it only has one value listed, the difference between variables A1 and A12. This is because PROC SQL does not recognize variable lists. You will need to list all of your variables.
select *,sum(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) as total
from have
;
If you want this in SQL because you're making use of other SQL functionality in addition to this, make a view.
data have_v/view=have_v;
set have;
total = sum(of a1-a12);
run;
proc sql;
select * from have_v; *presumably you do other things here;
quit;
In some cases you do not know how many variables there are or you don't want to hard code it. The syntax is in this case: sum(of < variable>:);
data test;
a1=1;
a2=2;
/*number 3 is missing*/
a4=4;
a5=5;
run;
data test2;
set test;
sum_of_all_As= sum(of a:);
run;
For more tips and tricks see: http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000245953.htm
We currently use the %runquit macro function as detailed here (http://analytics.ncsu.edu/sesug/2010/CC07.Blanchette.pdf). The %runquit macro is shown below. It basically stops running any more SAS code when an error is encounterd, and can be used as a replacement for both the run and quit statements:
%macro runquit;
; run; quit;
%if &syserr %then %abort cancel;
%mend;
Because using the outobs statement in proc sql triggers a system error (even when the nowarn option is specified) it means we are unable to use the %runquit macro when we need to use the outobs= option.
The below example will generate the following warning message:
proc sql noprint outobs=3 /*nowarn*/;
create table tmp as
select age, count(*) as freq
from sashelp.class
group by 1
order by 2 desc
;
%runquit;
WARNING: Statement terminated early due to OUTOBS=3 option.
Thank you SAS for the completely unnecessary warning. The behaviour is obviously expected because I explicitly wrote code to ask for it. I don't see warnings given when we specify inobs= and outobs= on a set statement. Why does proc sql get the special treatment?
Is there any way to disable the warning issues by the outobs= option in proc sql? Alternatively, is there another way to limit the output rows from proc sql that will not generate an error?
Assuming you are okay with the full SQL statement executing, you can get around this with a data step view that contains the obs limitation.
proc sql noprint ;
create table tmp as
select age, count(*) as freq
from sashelp.class
group by 1
order by 2 desc
;
%runquit;
data tmp_fin/view=tmp_fin;
set tmp(obs=3);
%runquit;
Or make the SQL statement a view and use the data step to make the data set.
proc sql noprint ;
create view tmp_view as
select age
, count(*) as freq
from sashelp.class
group by 1
order by 2 desc
;
quit;
data tmp;
set tmp_view(obs=3) ;
run;
This might be one of your options considering I/O is not a huge constraint, here the reset outobs= option with nowarn does the trick but at IOs cost.
proc sql;
create table test as
select * from sashelp.class;
reset outobs=10 nowarn;
create table test1 as
select * from sashelp.class;
quit;
By default it is defined to store macros at WORK.SASMACR.
However at my site location for macros storage is different and I do not know where it is.
Can I find the default macros catalog and view what is inside?
Please see below effects of system options SASMSTORE + MSTORED and STORE option in macro definition on location of the compiled macros - could be something similar was used on your site.
option sasmstore=sasuser mstored;
%macro _mstore /store;
%put This is macro with mstore;
%mend;
%macro _nomstore;
%put This is macro without mstore;
%mend;
proc options option=sasmstore;
run;
Use DICTIONARY.CATALOGS to list macros compiled in your session.
proc sql;
create table macros as
select * from dictionary.catalogs where objtype='MACRO';
quit;
You have three option to find macros `
1.
proc catalog catalog=work.SASMACR;
contents;
run;
2.
proc catalog catalog=work.SASMAC1;
contents;
run;
3.
proc sql;
create table macros as
select * from dictionary.catalogs where objtype='MACRO';
quit;
This is PROC SQL. Could anyone explain what I am getting as output ? Thanks !
proc sql;
select time into :date from end_date;
quit;
In addition to Chris J's answer, the INTO clause has a very versatile functionality. The following resources will give you very good overview.
Essentially using the INTO clause you can create a macro variable which holds a lists of items seperated by a custom delimiter, create a whole host of macro variables inside a single PROC SQL procedure - a task which could take multiple DATA _NULL_ steps & PROC SORT\MEANS\FREQ steps etc...
It is the PROC SQL equivalent of using %let date = <some time value>; or inside a datastep
DATA _NULL_;
set end_date;
call symputx("date", time);
RUN;
Using the Magical Keyword "INTO:" in PROC SQL
SAS(R) 9.2 Macro Language: Reference: INTO Clause
It simply puts the result into a macro variable, in this case the macro variable 'DATE' contains the time value off the record in the dataset end_date.