BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
current_thing
Obsidian | Level 7

Hello,

 

I'm stumped. I have two versions of a query syntax that should produce the same result but it doesn't!

Ver1:

select * from tbl where col1 contains "yes"

Ver2:

select * from tbl where col1 contains (select distinct test from xl.sheet1 where some_col="example")

The subquery (select distinct test from xl.sheet1 where some_col="example") from Ver2 returns "yes".

 

The problem is that Ver1 returns exactly as expected, but Ver2 returns just a fraction of Ver1. What am I missing here?

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

The issue is trailing spaces.  If the length of TEST is $8 then it returns 'yes     ' and not 'yes'.  So the contains will only match values of COL1 that yes followed by five spaces.

 

The only way I could get it to work is to add LENGTH= option to force the subquery to generate a value without trailing spaces.

data have;
  string='A ';
run;

proc sql;
select * from sashelp.class where name contains 'A';
%put &=sqlobs;
select * from sashelp.class where name contains (select string from have);
%put &=sqlobs;
select * from sashelp.class where name contains (select string length=1 from have);
%put &=sqlobs;
select * from have where string contains (select string from have);
%put &=sqlobs;
quit;

Also note that the subquery must only return on value.

 89         data have;
 90           input string $ ;
 91         cards;
 
 NOTE: The data set WORK.HAVE has 3 observations and 1 variables.
 NOTE: DATA statement used (Total process time):
       real time           0.00 seconds
       cpu time            0.00 seconds
       
 
 95         ;
 96         proc sql;
 97         select * from sashelp.class where name contains (select string from have);
 ERROR: Subquery evaluated to more than one row.
 NOTE: PROC SQL set option NOEXEC and will continue to check the syntax of statements.
 98         quit;
 NOTE: The SAS System stopped processing this step because of errors.
 NOTE: PROCEDURE SQL used (Total process time):
       real time           0.00 seconds
       cpu time            0.01 seconds

View solution in original post

5 REPLIES 5
LinusH
Tourmaline | Level 20

I did a simple test with sashelp.class and got expected result.

Can you post some test data (in form of a data step/datalines) so we can try your exact scenario?

Data never sleeps
Tom
Super User Tom
Super User

The issue is trailing spaces.  If the length of TEST is $8 then it returns 'yes     ' and not 'yes'.  So the contains will only match values of COL1 that yes followed by five spaces.

 

The only way I could get it to work is to add LENGTH= option to force the subquery to generate a value without trailing spaces.

data have;
  string='A ';
run;

proc sql;
select * from sashelp.class where name contains 'A';
%put &=sqlobs;
select * from sashelp.class where name contains (select string from have);
%put &=sqlobs;
select * from sashelp.class where name contains (select string length=1 from have);
%put &=sqlobs;
select * from have where string contains (select string from have);
%put &=sqlobs;
quit;

Also note that the subquery must only return on value.

 89         data have;
 90           input string $ ;
 91         cards;
 
 NOTE: The data set WORK.HAVE has 3 observations and 1 variables.
 NOTE: DATA statement used (Total process time):
       real time           0.00 seconds
       cpu time            0.00 seconds
       
 
 95         ;
 96         proc sql;
 97         select * from sashelp.class where name contains (select string from have);
 ERROR: Subquery evaluated to more than one row.
 NOTE: PROC SQL set option NOEXEC and will continue to check the syntax of statements.
 98         quit;
 NOTE: The SAS System stopped processing this step because of errors.
 NOTE: PROCEDURE SQL used (Total process time):
       real time           0.00 seconds
       cpu time            0.01 seconds
current_thing
Obsidian | Level 7

Tom, that worked! Length= in the subquery was the solution!

Ksharp
Super User

Or using STRIP() function to get rid of these heading/trailing blanks .

 

data have;
  string='A ';
run;

proc sql;
/*select * from sashelp.class where name contains 'A';*/
select * from sashelp.class where name contains strip((select string from have));
quit;
Tom
Super User Tom
Super User

That solves the problem of the subquery generating a character variable that is longer than the string it contains.  Note that it only works in this case because CONTAINS can only except one value from the subquery.  So there is no conflict with the fact that the STRIP() function can only operate on one value at a time.

Catch up on SAS Innovate 2026

Dive into keynotes, announcements and breakthroughs on demand.

Explore 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
  • 5 replies
  • 708 views
  • 3 likes
  • 4 in conversation