BookmarkSubscribeRSS Feed
Aexor
Lapis Lazuli | Level 10

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..

 

11 REPLIES 11
Mazi
Pyrite | Level 9
Hi,

I’m not sure I understand the actual problem?

Can you send a screenshot of your log with the macro call.

Please turn on options MPRINT and symbolgen
ballardw
Super User

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,

PaigeMiller
Diamond | Level 26

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.

PaigeMiller_0-1663012019648.png

 

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

--
Paige Miller
Aexor
Lapis Lazuli | Level 10
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

Tom
Super User Tom
Super User

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)
Aexor
Lapis Lazuli | Level 10
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
Tom
Super User Tom
Super User

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.

Kurt_Bremser
Super User

@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.

Kurt_Bremser
Super User
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?

PaigeMiller
Diamond | Level 26

@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.

--
Paige Miller
Kurt_Bremser
Super User

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.

SAS Innovate 2025: Register Now

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!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 11 replies
  • 1328 views
  • 0 likes
  • 6 in conversation