<?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: Counting the number of company holidays worked between two dates - across 2 different tables in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787162#M251455</link>
    <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/187116"&gt;@calger&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;Won't this result in cross join that takes forever to execute? Is there a&lt;BR /&gt;better way?&lt;BR /&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Well the criteria don't include equijoins or other proximity conditions, so a cartesian join is unavoidable in this case.&lt;/P&gt;
&lt;P&gt;This does not mean it takes forever. What are the volumes?&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It takes 50 seconds for 1m times 800 records on my old PC.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data EMP;
  do ID=1 to 1e6;
    START=ranuni(1)*20000;
    END  =START+ranuni(1)*5000;
    output;
  end;
run;
data HOL;
  do DAY=1 to 25000;
    if ranuni(1)&amp;gt;.97 then output;
  end;
run;
proc sql _method;
  create table WANT as 
  select ID, START, END, count(DAY) 
  from EMP left join HOL 
  on DAY between START and END
  group by ID, START, END;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 22 Dec 2021 20:47:37 GMT</pubDate>
    <dc:creator>ChrisNZ</dc:creator>
    <dc:date>2021-12-22T20:47:37Z</dc:date>
    <item>
      <title>Counting the number of company holidays worked between two dates - across 2 different tables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/786985#M251354</link>
      <description>&lt;P&gt;Hello, I am trying to count the number of company-specific holidays an employee has worked between two different dates.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;There is a Holiday table which lists the company holidays, starting from 2013 and going through 2025. So, there is 12-25-2013, 12-25-2014, etc. Then there are the holidays that change date every year, such as Thanksgiving and the day after Thanksgiving, etc. I cannot use the SAS holiday function because it includes days my company does not take off.&lt;/P&gt;&lt;P&gt;HOLIDAY_ID HOLIDAY_DATE&lt;/P&gt;&lt;P&gt;1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;12/25/2013&lt;/P&gt;&lt;P&gt;2&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;01/01/2014&lt;/P&gt;&lt;P&gt;3&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;05/27/2014&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;There is a table with employees working different time spans. There are more columns involved, but essentially, it looks like this:&lt;/P&gt;&lt;P&gt;EMP_ID&amp;nbsp; WORK_START&amp;nbsp; &amp;nbsp;WORK_END_DATE&lt;/P&gt;&lt;P&gt;1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;12/24/2013&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 05/26/2014&lt;/P&gt;&lt;P&gt;2&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 12/24/2013&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 06/01/2014&lt;/P&gt;&lt;P&gt;3&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;01/06/2014&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;03/23/2014&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Basically, for each employee (EMP_ID) I need the number of rows in the Holiday table equal to the number of holidays between WORK_START and WORK_END DATE. Aka "Want" table looks like&lt;/P&gt;&lt;P&gt;EMP_ID&amp;nbsp; WORK_START&amp;nbsp; WORK_END_DATE&amp;nbsp; HOLIDAY_COUNT&lt;/P&gt;&lt;P&gt;1&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;12/24/2013&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 05/26/2014&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2&lt;/P&gt;&lt;P&gt;2&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 12/24/2013&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 06/01/2014&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;3&lt;/P&gt;&lt;P&gt;3&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;01/06/2014&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;03/23/2014&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The employee work table is pretty large.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm sure this is something that's been solved before and is probably simple, but I cannot find a solution online. Thank you!&lt;/P&gt;&lt;P&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 21 Dec 2021 17:35:52 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/786985#M251354</guid>
      <dc:creator>calger</dc:creator>
      <dc:date>2021-12-21T17:35:52Z</dc:date>
    </item>
    <item>
      <title>Re: Counting the number of company holidays worked between two dates - across 2 different tables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787026#M251382</link>
      <description>&lt;P&gt;Like this?&lt;/P&gt;
&lt;P&gt;proc sql;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; select&amp;nbsp;&lt;SPAN&gt;EMP_ID, WORK_START, WORK_END_DATE, count(HOLIDAY_DATE) as HOLIDAY_COUNT&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp; from EMPLOYEE left join HOLIDAYS&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&amp;nbsp; on HOLIDAY_DATE between WORK_START and WORK_END_DATE&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 21 Dec 2021 23:16:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787026#M251382</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2021-12-21T23:16:14Z</dc:date>
    </item>
    <item>
      <title>Re: Counting the number of company holidays worked between two dates - across 2 different tables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787073#M251405</link>
      <description>&lt;P&gt;Another solution: using an array as lookup:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
   call symputx('num_holidays', num_holidays);
   if 0 then set work.holidays nobs=num_holidays;
run;

data want;
   set work.emps;

   length holiday_count 8;

   array holidays[&amp;amp;num_holidays.] _temporary_;

   if _n_ = 1 then do;
      do i = 1 to num_holidays;
         set work.holidays nobs= num_holidays;
         holidays[i] = holiday_date;
      end;
   end;

   holiday_count = 0;

   do i = 1 to dim(holidays);
      holiday_count = holiday_count + (work_start &amp;lt;= holidays[i] &amp;lt;= work_end);
   end;

   drop i holiday_date holiday_id;
run;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 22 Dec 2021 09:07:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787073#M251405</guid>
      <dc:creator>andreas_lds</dc:creator>
      <dc:date>2021-12-22T09:07:44Z</dc:date>
    </item>
    <item>
      <title>Re: Counting the number of company holidays worked between two dates - across 2 different tables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787088#M251413</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data holiday;
input HOLIDAY_ID HOLIDAY_DATE : mmddyy12.;
format HOLIDAY_DATE  mmddyy10. ;
cards;
1                 12/25/2013
2                 01/01/2014
3                 05/27/2014
;

data have;
input EMP_ID  WORK_START  : mmddyy12. WORK_END_DATE : mmddyy12.;
format WORK_START WORK_END_DATE mmddyy10. ;
cards;
1                 12/24/2013          05/26/2014
2                  12/24/2013          06/01/2014
3                 01/06/2014           03/23/2014
;

data want;
 if _n_=1 then do;
  if 0 then set holiday(keep=HOLIDAY_DATE);
  declare hash h(dataset:'holiday(keep=HOLIDAY_DATE)');
  h.definekey('HOLIDAY_DATE');
  h.definedone();
 end;
set have;
HOLIDAY_COUNT=0;
do i=WORK_START to WORK_END_DATE;
 if h.check(key:i)=0 then HOLIDAY_COUNT+1;
end;
drop i  HOLIDAY_DATE;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 22 Dec 2021 12:11:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787088#M251413</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2021-12-22T12:11:25Z</dc:date>
    </item>
    <item>
      <title>Re: Counting the number of company holidays worked between two dates - across 2 different tables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787090#M251414</link>
      <description>Won't this result in cross join that takes forever to execute? Is there a&lt;BR /&gt;better way?&lt;BR /&gt;</description>
      <pubDate>Wed, 22 Dec 2021 12:42:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787090#M251414</guid>
      <dc:creator>calger</dc:creator>
      <dc:date>2021-12-22T12:42:14Z</dc:date>
    </item>
    <item>
      <title>Re: Counting the number of company holidays worked between two dates - across 2 different tables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787093#M251415</link>
      <description>&lt;P&gt;And another solution: A data-null-step is used to create a data step that does all the work.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data work.holidays;
   input holiday_id holiday_date mmddyy10.;
   datalines;
1 12/25/2013
2 01/01/2014
3 05/27/2014
;

data work.emps;
   length emp_id 8 work_start work_end 8;
   informat work_: mmddyy10.;
   format work_: date9.;
   input emp_id work_start work_end;
   datalines;
1 12/24/2013 05/26/2014
2 12/24/2013 06/01/2014
3 01/06/2014 03/23/2014
;

data _null_;
   set work.holidays end= jobDone;

   length dummy $ 100;

   if _n_ = 1 then do;
      call execute('data work.want; set work.emps;');
      call execute('holiday_count =');
   end;

   dummy = '';

   if _n_ &amp;gt; 1 then do;
      dummy = '+';
   end;

   dummy = catx(' ',  dummy, '(work_start &amp;lt;=', holiday_date, '&amp;lt;= work_end)');
   call execute(dummy);

   put '  ' dummy;
   if jobDone then do;
      call execute('; run;');
   end;
run;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 22 Dec 2021 13:13:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787093#M251415</guid>
      <dc:creator>andreas_lds</dc:creator>
      <dc:date>2021-12-22T13:13:12Z</dc:date>
    </item>
    <item>
      <title>Re: Counting the number of company holidays worked between two dates - across 2 different tables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787162#M251455</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/187116"&gt;@calger&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;Won't this result in cross join that takes forever to execute? Is there a&lt;BR /&gt;better way?&lt;BR /&gt;&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Well the criteria don't include equijoins or other proximity conditions, so a cartesian join is unavoidable in this case.&lt;/P&gt;
&lt;P&gt;This does not mean it takes forever. What are the volumes?&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It takes 50 seconds for 1m times 800 records on my old PC.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data EMP;
  do ID=1 to 1e6;
    START=ranuni(1)*20000;
    END  =START+ranuni(1)*5000;
    output;
  end;
run;
data HOL;
  do DAY=1 to 25000;
    if ranuni(1)&amp;gt;.97 then output;
  end;
run;
proc sql _method;
  create table WANT as 
  select ID, START, END, count(DAY) 
  from EMP left join HOL 
  on DAY between START and END
  group by ID, START, END;
quit;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 22 Dec 2021 20:47:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787162#M251455</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2021-12-22T20:47:37Z</dc:date>
    </item>
    <item>
      <title>Re: Counting the number of company holidays worked between two dates - across 2 different tables</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787192#M251470</link>
      <description>&lt;P&gt;The good thing about using an array is you can stop the cartesian match before it is fully complete, when the holidays come after the end date.&amp;nbsp;For example this runs faster than the proc SQL.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
   call symputx('num_holidays', NUM_HOLIDAYS);
   if 0 then set HOL nobs=NUM_HOLIDAYS;
run;

data WANT2;
  set EMP;
  array HOLIDAYS[&amp;amp;num_holidays.] _temporary_;

  if _N_ = 1 then do I = 1 to NUM_HOLIDAYS;
    set HOL nobs= NUM_HOLIDAYS;
    HOLIDAYS[I] = DAY;
  end;

  do I = 1 to dim(HOLIDAYS) until (HOLIDAYS[I] &amp;gt; END);  
    HOLIDAY_COUNT = sum(HOLIDAY_COUNT, START &amp;lt;= HOLIDAYS[I] &amp;lt;= END );
  end;

  keep ID START END HOLIDAY_COUNT;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 23 Dec 2021 03:29:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Counting-the-number-of-company-holidays-worked-between-two-dates/m-p/787192#M251470</guid>
      <dc:creator>ChrisNZ</dc:creator>
      <dc:date>2021-12-23T03:29:24Z</dc:date>
    </item>
  </channel>
</rss>

