Hi All
I have this query
proc sql;
create table &val._member as
select
t1.member_cd as member_id,
t2.member_nm,
t2.member_desc,
%do j = 1 %to %sysfunc(countw(&prop_cd));
%let prop_value = %scan(&prop_cd, &j);
t3.property_value as &prop_value,
%end;
t2.valid_from_dttm,
t2.valid_to_dttm
from
&val._mem_det t1
left join &planning_lib..SAS_MEMBER_NLS t2
on
t1.member_id = t2.member_id
left join &planning_lib..SAS_MEMBER_PROPERTY t3
on
t1.member_id = t3.member_id and property_id in (&prop_id);
quit;
In the highlighted do loop section prop_cd macro is having some value , whenever count > 1, loop is getting iterated and I am getting duplicates value = records* countw(&prop_cd))..
Kindly please help me to correct this.. my main aim to use do loop to resolve the columns
t3.property_value as colA,
t3.property_value as colB,
t3.property_value as colC,
like that..
Did you have code that produced the desired output before you introduced the macro variables?
Without any macro loop?
If so, show us that code.
Any time you reference macro variables in code for questions you should include the definitions of the variables, especially one like your &Prop_cd where you are pulling pieces from it for other use.
This will always assign the same value to 3 variables. Is that actually the intent as doesn't make a lot of sense to me.
t3.property_value as colA,
t3.property_value as colB,
t3.property_value as colC,
Show us the ENTIRE log for this PROC SQL code. First, turn on the macro debugging options by running this command.
options symbolgen mprint;
Then run your code and check the log, you might see why this is happening. If its still not clear to you, show us the log as explained above. Please copy the log as text and then paste it into the window that appears when you click on the </> icon. DO NOT SKIP THIS STEP.
Also please explain this part more:
Kindly please help me to correct this.. my main aim to use do loop to resolve the columns
t3.property_value as colA,
t3.property_value as colB,
t3.property_value as colC,
like that..
It's not clear what code you mean by "resolve" here, and it's not clear what code you WANT to produce from this macro
code without macro proc sql; create table veh_det as select * from &planning_lib..SAS_member where internal_dimension_id = -17 and internal_dim_type_id = -20; quit; proc sql; select distinct property_id into:prop_id separated by ',' from &planning_lib..sas_member_property where internal_dimension_id = -17; quit; %put property_id : &prop_id ; proc sql; select distinct property_cd into:prop_cd separated by ' ' from &planning_lib..sas_property where property_id in (&prop_id); quit; %put &prop_cd; proc sql; create table veh_member as select t1.member_cd as member_id, t2.member_nm, t2.member_desc, t3.property_value as promo_support, t3.property_value as vehicle_name, t3.property_value as levelname, t2.valid_from_dttm, t2.valid_to_dttm from veh_det t1 join &planning_lib..SAS_MEMBER_NLS t2 on t1.member_id = t2.member_id join &planning_lib..SAS_MEMBER_PROPERTY t3 on t1.member_id = t3.member_id and property_id in (&prop_id); quit;
log /; 79 80 proc sql; 81 create table veh_det as 82 select * 83 from &planning_lib..SAS_member 84 where internal_dimension_id = -17 85 and internal_dim_type_id = -20; NOTE: Table WORK.VEH_DET created, with 12 rows and 10 columns. 86 quit; NOTE: PROCEDURE SQL used (Total process time): real time 0.04 seconds cpu time 0.03 seconds 87 88 proc sql; 89 select distinct property_id into:prop_id separated by ',' 90 from &planning_lib..sas_member_property 91 where internal_dimension_id = -17; 92 quit; NOTE: The PROCEDURE SQL printed page 9. NOTE: PROCEDURE SQL used (Total process time): real time 0.04 seconds cpu time 0.02 seconds 93 94 %put property_id : &prop_id ; property_id : 27,31,32 95 96 proc sql; 97 select distinct property_cd into:prop_cd separated by ' ' 98 from &planning_lib..sas_property 99 where property_id in (&prop_id); 100 quit; NOTE: The PROCEDURE SQL printed page 10. NOTE: PROCEDURE SQL used (Total process time): real time 0.03 seconds cpu time 0.03 seconds 101 102 %put &prop_cd; PROMO_SUPPORT VEHICLE_TYPE LEVELNAME 103 104 proc sql; 105 create table veh_member as 106 select 107 t1.member_cd as member_id, 108 t2.member_nm, 109 t2.member_desc, 110 t3.property_value as promo_support, 111 t3.property_value as vehicle_type, 112 t3.property_value as levelname, 113 t2.valid_from_dttm, 114 t2.valid_to_dttm 115 from 116 veh_det t1 117 join &planning_lib..SAS_MEMBER_NLS t2 118 on 119 t1.member_id = t2.member_id 120 join &planning_lib..SAS_MEMBER_PROPERTY t3 121 on 122 t1.member_id = t3.member_id and property_id in (&prop_id); NOTE: Table WORK.VEH_MEMBER created, with 35 rows and 8 columns. 123 quit; NOTE: PROCEDURE SQL used (Total process time): real time 0.13 seconds cpu time 0.11 seconds 124 125 126 /* region: Generated postamble */ 127 /* Close ODS destinations */ 128 &graphterm; ;*';*";*/;run;quit; 129 quit;run; 130 ods html5 (id=web) close; 131 ods listing close; 132 %if %sysfunc(fileref(_gsfname)) lt 0 %then %do; 133 filename _gsfname clear; NOTE: Fileref _GSFNAME has been deassigned. 134 %end; 135 %studio_capture_custom_output; 136 /* endregion */ 137
here from 12records in veh_detail is converted to having 36 records in veh_member .
its 12* 3 = 36 as 3 columns is getting printed
Please explain what you are trying to do. Can you provide a few observations for each of the datasets involved that will demonstrate the issue? Please provide as SAS code to create the datasets. Simple data steps with INPUT statement with in-line CARDS (aka DATALINES) is the easiest way to share sample data.
Sounds like you did a JOIN where you joined every observation with 3 observations and so you get 3 times as many observations out as you started with.
The normal way to prevent that is to match to just one of the 3 that makes the most sense.
Do you have variables on the two tables that you can include in the ON join condition so that instead of matching all 3 you only match one of the 3? Since you are picking 3 values of property_id that looks like the place to start.
Does property_id exist on the dataset you have aliased asT1? If so include that in the last ON condition.
join &planning_lib..SAS_MEMBER_PROPERTY t3
on t1.member_id = t3.member_id
and t1.property_id = t3.property_id
and t3.property_id in (&prop_id)
There is a disconnect here. You are using PROC_CD to look up values of a variable and put them into a macro variable.
But now you are saying you are to treat those as variable names. Does that mean the table you queried was metadata and not data?
Or does it mean that the final table has NAME/VALUE pairs? Something like:
property_code property_value
promo_support XXXX
vehicle_name YYYY
levelname ZZZZ
If so then I suspect you want three joins and not what you have.
See is you can modify your basic query to produce what you want without any macro code.
So something like:
select T1.*
, P1.property_value as promo_support
, P2.property_value as vehicle_name
, P3.property_value as levelname
from main_table T1
left join sub_table P1 on T1.id = P1.id and P1.property_code="promo_support"
left join sub_table P2 on T1.id = P2.id and P2.property_code="vehicle_name"
left join sub_table P3 on T1.id = P3.id and P3.property_code="levelname"
if do then you can just introduce two %D0 loops. One to generate the list of fields and the second to generate the series of joins.
@Aexor wrote:
Sorry , t1 t1.property_id is not having this column..
My idea was to add
t3.property_value as
promo_support,
t3.property_value as vehicle_name,
t3.property_value as levelname, add these column, but the number of column may change based on prop_Cd
t1.property IS a column, it can't HAVE one. You're talking nonsense.
t3.property_value as promo_support,
t3.property_value as vehicle_name,
t3.property_value as levelname,
So what is the purpose of creating this redundancy?
@Aexor wrote:
here from 12records in veh_detail is converted to having 36 records in veh_member .its 12* 3 = 36 as 3 columns is getting printed
Please EXPLAIN further. Or show us. We don't understand. You also talk about records and then talk about columns in the next sentence, as if they were the same thing. In the original post, you highlighted a portion of code that cannot produce duplicate records but would produce "duplicate" columns (with different names).
In your original post, you talk about duplicate records as well, which cannot be caused by the highlighted portion of the text:
In the highlighted do loop section prop_cd macro is having some value , whenever count > 1, loop is getting iterated and I am getting duplicates value = records* countw(&prop_cd))..
Please clear this up for us. Is the problem duplicate records or duplicate columns?
We need an explanation in words, we need you to clearly explain what you want. Show us both the results as they exist and then show us the results that you would like.
First, write non-macro code which creates what you want. Then, look at ways to streamline it through the use of macro coding.
Always keep in mind that the macro processor is a code generator, and to successfully use it, you have to know which code it should create.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.