<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: SAS SQL: Setting values to NULL in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478140#M286306</link>
    <description>&lt;P&gt;&lt;EM&gt;[Editors Note]&lt;/EM&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;I've marked&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;&amp;nbsp;response as the accepted solution as it is concise and offers both SQL and Data Step solutions. I also recommend you read the replies from&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/16961"&gt;@ChrisNZ&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt;&amp;nbsp;who add valuable additional information&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;[End Editors Note]&lt;/EM&gt;&lt;BR /&gt;&lt;BR /&gt;To represent a missing numeric value use a period.&amp;nbsp; For a missing character value then just use a string literal that only contains blanks.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql ;
  select name
        ,age,case when name='Alice' then . else age end as age2
        ,sex,case when name='Alfred' then ' ' else sex end as sex2
  from sashelp.class
  where name in ('Alice','Alfred')
  ;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;It is much easier if you just use regular SAS syntax instead of trying to use PROC SQL.&amp;nbsp; Then you can use the CALL MISSING() function to make the value missing without having to know whether the field is numeric or character.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data DIAG_NEW
  merge diag(in=in1) ENC(keep=id in=in2) ;
  by id;
  if in1;
  if not in2 then call missing(id);
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 19 Aug 2022 11:55:20 GMT</pubDate>
    <dc:creator>Tom</dc:creator>
    <dc:date>2022-08-19T11:55:20Z</dc:date>
    <item>
      <title>SAS SQL: Setting values to NULL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478088#M286303</link>
      <description>&lt;P&gt;Hi SAS users,&lt;/P&gt;&lt;P&gt;I have a baseline SAS dataset ENC with a primary key&amp;nbsp;ID. I have a second dataset DIAG with ID as a foreign key. For values of ID that do not link, I need to set ID to NULL in the DIAG dataset. Assume there is no way to fix the source data.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried&amp;nbsp;about 20 variations of&amp;nbsp;the&amp;nbsp;proc sql step below but nothing works yet.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;proc sql;
   create table DIAG_NEW as
   select field1
      ,field2
      ,case when ID in (select ID from ENC) then ID
            else ID is NULL end as ID
   from DIAG;
quit;&lt;BR /&gt;&lt;BR /&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 14 Jul 2018 02:45:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478088#M286303</guid>
      <dc:creator>sobrio40</dc:creator>
      <dc:date>2018-07-14T02:45:01Z</dc:date>
    </item>
    <item>
      <title>Re: SAS SQL: Setting values to NULL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478089#M286304</link>
      <description>&lt;P&gt;Don't have any data to test this with but something like this should work. When there is no matching row in ENC ID_ENC will be blank.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql;
   create table DIAG_NEW as
   select field1
      ,field2
      ,E.ID as ID_ENC
   from DIAG as D
   left join ENC as E
   on D.ID = E.ID;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 14 Jul 2018 03:21:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478089#M286304</guid>
      <dc:creator>SASKiwi</dc:creator>
      <dc:date>2018-07-14T03:21:26Z</dc:date>
    </item>
    <item>
      <title>Re: SAS SQL: Setting values to NULL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478090#M286305</link>
      <description>&lt;P&gt;Try this syntax:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql;
   create table DIAG_NEW as
   select field1
      ,field2
      ,case when ID in (select ID from ENC) then ID
            else . end as ID
   from DIAG;
quit;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 14 Jul 2018 03:28:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478090#M286305</guid>
      <dc:creator>PGStats</dc:creator>
      <dc:date>2018-07-14T03:28:44Z</dc:date>
    </item>
    <item>
      <title>Re: SAS SQL: Setting values to NULL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478140#M286306</link>
      <description>&lt;P&gt;&lt;EM&gt;[Editors Note]&lt;/EM&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;I've marked&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;&amp;nbsp;response as the accepted solution as it is concise and offers both SQL and Data Step solutions. I also recommend you read the replies from&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/16961"&gt;@ChrisNZ&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/11562"&gt;@Kurt_Bremser&lt;/a&gt;&amp;nbsp;who add valuable additional information&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;[End Editors Note]&lt;/EM&gt;&lt;BR /&gt;&lt;BR /&gt;To represent a missing numeric value use a period.&amp;nbsp; For a missing character value then just use a string literal that only contains blanks.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql ;
  select name
        ,age,case when name='Alice' then . else age end as age2
        ,sex,case when name='Alfred' then ' ' else sex end as sex2
  from sashelp.class
  where name in ('Alice','Alfred')
  ;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;It is much easier if you just use regular SAS syntax instead of trying to use PROC SQL.&amp;nbsp; Then you can use the CALL MISSING() function to make the value missing without having to know whether the field is numeric or character.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data DIAG_NEW
  merge diag(in=in1) ENC(keep=id in=in2) ;
  by id;
  if in1;
  if not in2 then call missing(id);
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 19 Aug 2022 11:55:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478140#M286306</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2022-08-19T11:55:20Z</dc:date>
    </item>
    <item>
      <title>Re: SAS SQL: Setting values to NULL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478273#M286307</link>
      <description>&lt;P&gt;It's a good habit to avoid embedded select clauses as they are inefficient (though not a performance killer when just building a list as you are here).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data DIAG ENC;
  do ID=1 to 2e7;
    output; 
  end; 
run;

proc sql;  * 40 seconds;
   create table DIAG_NEW as
   select case when ID in (select ID from ENC) then ID
          else . end as ID
   from DIAG;
quit;

proc sql; * 16 seconds;
   create table DIAG_NEW as
   select E.ID as ID_ENC
   from DIAG as D
   left join ENC as E
   on D.ID = E.ID;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 16 Jul 2018 04:15:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/478273#M286307</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2018-07-16T04:15:44Z</dc:date>
    </item>
    <item>
      <title>Re: SAS SQL: Setting values to NULL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/690761#M286308</link>
      <description>&lt;P&gt;nice solution&lt;/P&gt;</description>
      <pubDate>Sun, 11 Oct 2020 06:17:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/690761#M286308</guid>
      <dc:creator>roberthi</dc:creator>
      <dc:date>2020-10-11T06:17:21Z</dc:date>
    </item>
    <item>
      <title>Re: SAS SQL: Setting values to NULL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/690779#M286309</link>
      <description>&lt;P&gt;Out of curiosity, I ran a test with a hash object and some "payload data" on my UE:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data
  myfold.DIAG
  myfold.ENC (keep=id)
;
length payload $200;
payload = repeat("X",199);
do ID=1 to 6e6;
  output myfold.diag;
  if mod(id,5) = 0 then output myfold.enc;
end; 
run; /* 7.77 seconds */

proc sql;
   create table myfold.DIAG_NEW1 as
   select
     id,
     payload,
     case
       when ID in (select ID from myfold.ENC)
       then ID
       else .
     end as enc_ID
   from myfold.DIAG;
quit; /* 21.61 seconds */

proc sql;
   create table myfold.DIAG_NEW2 as
   select
     d.id,
     d.payload,
     E.ID as ID_ENC
   from myfold.DIAG as D
   left join myfold.ENC as E
   on D.ID = E.ID;
quit; /* 1:07.10 (!) */

data myfold.diag_new3;
set myfold.diag;
if _n_ = 1
then do;
  declare hash h (dataset:"myfold.enc",hashexp:7);
  h.definekey("id");
  h.definedone();
end;
if h.check() = 0 then enc_id = id;
run; /* 14.74 seconds */

data myfold.diag_new4;
merge
  myfold.diag (in=d)
  myfold.enc (in=e)
;
by id;
if d;
if e then enc_id = id;
run; /* 13.41 seconds */&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;As you can see, the addition of payload data caused the join to turn into a performance nightmare.&lt;/P&gt;
&lt;P&gt;Unsurprisingly, the data step methods performed best.&lt;/P&gt;</description>
      <pubDate>Sun, 11 Oct 2020 11:04:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/690779#M286309</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2020-10-11T11:04:35Z</dc:date>
    </item>
    <item>
      <title>Re: SAS SQL: Setting values to NULL</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/690874#M286310</link>
      <description>&lt;P&gt;My test results, which are in line with my expectations:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data
  WORK.DIAG 
  WORK.ENC (keep=ID)
  ;
  length PAYLOAD $200;
  PAYLOAD = repeat("X",199);
  do ID=1 to 1e7;
    output WORK.DIAG;
    if mod(ID,5) = 0 then output WORK.ENC;
  end; 
run; /* 5.87 seconds */

proc sql;
   create table WORK.DIAG_NEW1 as
   select
     ID,
     PAYLOAD,
     case
       when ID in (select ID from WORK.ENC)
       then ID
       else .
     end as ENC_ID
   from WORK.DIAG;
quit;                                 /* in (select ...) 27.59 seconds */

proc sql _method;
   create table WORK.DIAG_NEW2 as
   select
     d.ID,
     d.PAYLOAD,
     E.ID as ID_ENC
   from WORK.DIAG     as d
   left join WORK.ENC as e
   on D.ID = E.ID;
quit;                                  /* left join 24:05 */                 

data WORK.DIAG_NEW3;
set WORK.DIAG;
  if _n_ = 1 then do;
    declare hash h (dataset:"WORK.ENC",hashexp:7);
    h.definekey("ID");
    h.definedone();
  end;
  if h.check() = 0 then ENC_ID = ID;
run;                                   /* hash 15.08 seconds */

data WORK.DIAG_NEW4;
merge
  WORK.DIAG (in=D)
  WORK.ENC  (in=E)
  ;
  by ID;
  if D;
  if E then ENC_ID = ID;
run;                                   /* merge by 10.41 seconds */


data
  WORK.DIAG(sortedby=ID) 
  WORK.ENC (sortedby=ID keep=ID)
  ;
  length PAYLOAD $200;
  PAYLOAD = repeat("X",199);
  do ID=1 to 1e7;
    output WORK.DIAG;
    if mod(ID,5) = 0 then output WORK.ENC;
  end; 
run; /* 5.24 seconds */

proc sql _method;
   create table WORK.DIAG_NEW2 as
   select
     d.ID,
     d.PAYLOAD,
     e.ID as ID_ENC
   from WORK.DIAG     as d
   left join WORK.ENC as e
   on D.ID = E.ID;
quit;                              /* left join sorted 12.24 seconds */&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The worst time is:&amp;nbsp; in (select...), which is very inefficient as expected (it's basically a Cartesian product).&lt;/P&gt;
&lt;P&gt;Then a SQL join with bad metadata (proc sql doesn't know the data is already sorted so sorts both tables again).&lt;/P&gt;
&lt;P&gt;Then hash.&lt;/P&gt;
&lt;P&gt;Then the SQL join without sort&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then the data step merge, which leverages the sorted data the best.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note: WORK library uses the BASE engine.&lt;/P&gt;
&lt;P&gt;When using SPDE, the data step takes longer than proc sql.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 12 Oct 2020 02:23:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-SQL-Setting-values-to-NULL/m-p/690874#M286310</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2020-10-12T02:23:10Z</dc:date>
    </item>
  </channel>
</rss>

