<?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: Getting Consecutive Days in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225949#M40616</link>
    <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Below is another pure PROC SQL approach. It uses a self-join twice to (detect earlier and later rows) and&amp;nbsp;enables two rows being&amp;nbsp;collapsed into one. However, it does not deal with collapsing three or more rows into one; not sure if that kind of scenario would happen in your data, based on the example you provided.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;PROC SQL;
  CREATE TABLE have (
    id        num, 
    startdate num format=date11., 
    enddate   num format=date11.);
QUIT;


PROC SQL;
INSERT INTO have
values (101, '15-Dec-2013'd, '15-Dec-2013'd)
values (101, '16-Dec-2013'd, '16-Dec-2013'd)
values (101, '28-Dec-2013'd, '28-Dec-2013'd)
values (101, '29-Dec-2013'd, '31-Dec-2013'd)
/* add some additional data for good measure ... */
/* note that there are 3 consecutive rows (1/15 to 1/28/2014) */
/* values (201, '15-Jan-2014'd, '17-Jan-2014'd) */
/* values (201, '18-Jan-2014'd, '26-Jan-2014'd) */
/* values (201, '27-Jan-2014'd, '28-Jan-2014'd) */
/* values (201, '01-Feb-2014'd, '01-Feb-2014'd) */
;
QUIT;


PROC SQL;
  CREATE TABLE want AS 
  SELECT id
       , startdate
       , coalesce(nextRow_enddate, enddate) format=date11. AS wanted_enddate
  /* subquery joins current row to earlier row and future row (if they exist) */
  FROM (SELECT aa.id
             , aa.startdate
             , aa.enddate
             , monotonic()   as seq_num
             , next.enddate  as nextRow_enddate
             , prior.enddate as priorRow_enddate
        FROM have as aa
        LEFT JOIN have as next
               ON next.id = aa.id
              AND next.startdate = aa.enddate+1
        LEFT JOIN have as prior
               ON prior.id = aa.id
              AND prior.enddate = aa.startdate-1
        WHERE priorRow_enddate IS NULL) as qry;
QUIT;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 16 Sep 2015 21:29:42 GMT</pubDate>
    <dc:creator>hbi</dc:creator>
    <dc:date>2015-09-16T21:29:42Z</dc:date>
    <item>
      <title>Getting Consecutive Days</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225818#M40577</link>
      <description>&lt;P&gt;I have two tables which I need to combine as sometimes some dates are found in table A and not in table B and vice versa. My desired result is that for those overlaps on consecutive days be combined.&lt;/P&gt;&lt;P&gt;How can I achieve this using proc SQL only?&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Table A&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class="lang-sql prettyprint prettyprinted"&gt;&lt;CODE&gt;&lt;SPAN class="pln"&gt;id  startdate   enddate&lt;/SPAN&gt;&lt;SPAN class="com"&gt;--------------------------&lt;/SPAN&gt;
&lt;SPAN class="lit"&gt;101&lt;/SPAN&gt; &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;28&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;  &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;31&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;STRONG&gt;Table B&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class="lang-sql prettyprint prettyprinted"&gt;&lt;CODE&gt;&lt;SPAN class="pln"&gt;id  startdate   enddate&lt;/SPAN&gt;&lt;SPAN class="com"&gt;--------------------------&lt;/SPAN&gt;
&lt;SPAN class="lit"&gt;101&lt;/SPAN&gt; &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;15&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;  &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;15&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;
&lt;SPAN class="lit"&gt;101&lt;/SPAN&gt; &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;16&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;  &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;16&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;
&lt;SPAN class="lit"&gt;101&lt;/SPAN&gt; &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;28&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;  &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;28&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;
&lt;SPAN class="lit"&gt;101&lt;/SPAN&gt; &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;29&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;  &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;31&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;STRONG&gt;Desired Result&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class="lang-sql prettyprint prettyprinted"&gt;&lt;CODE&gt;&lt;SPAN class="pln"&gt;id  startdate   enddate&lt;/SPAN&gt;&lt;SPAN class="com"&gt;-------------------------&lt;/SPAN&gt;
&lt;SPAN class="lit"&gt;101&lt;/SPAN&gt; &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;15&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;  &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;16&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;
&lt;SPAN class="lit"&gt;101&lt;/SPAN&gt; &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;28&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;  &lt;SPAN class="lit"&gt;12&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;31&lt;/SPAN&gt;&lt;SPAN class="pun"&gt;/&lt;/SPAN&gt;&lt;SPAN class="lit"&gt;2013&lt;/SPAN&gt;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 16 Sep 2015 12:58:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225818#M40577</guid>
      <dc:creator>milts</dc:creator>
      <dc:date>2015-09-16T12:58:38Z</dc:date>
    </item>
    <item>
      <title>Re: Getting Consecutive Days</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225867#M40592</link>
      <description>&lt;P&gt;It appears that you are collapsing intervals from data set B. Are you doing the same from dataset A? You should include an example for the data set A that clearly isn't in B so we have some more idea what is going on as I can see the final result coming only from B.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And why a restriction for proc sql only? Since order is important that restriction may add complexity to code that could be very straight forward in data step code.&lt;/P&gt;</description>
      <pubDate>Wed, 16 Sep 2015 15:25:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225867#M40592</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2015-09-16T15:25:56Z</dc:date>
    </item>
    <item>
      <title>Re: Getting Consecutive Days</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225893#M40598</link>
      <description>&lt;P&gt;Sometimes solving problems are all about choosing the right tools. Like &lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13884"&gt;@ballardw﻿&lt;/a&gt;&amp;nbsp;mentioned, data step is the right tool for this kind of task.&amp;nbsp;That said, it still can be done using Proc SQL, but you may not like the complexity of the code:&lt;/P&gt;&lt;PRE&gt;proc sql;
	create table have as
		select * from table_a
			union corr
		select * from table_b
	;
quit;

proc sql;
	create table want_sql as    
		select distinct id, min(startdate, (select min(startdate) from have where id=a.id and (startdate between a.startdate-1 and a.enddate+1 
			or enddate between a.startdate and a.enddate or a.startdate between startdate-1 and enddate+1 or a.enddate between startdate and enddate))) as startdate format=date9.,
			max(enddate, (select max(enddate) from have where id=a.id and (startdate between a.startdate-1 and a.enddate+1 
			or enddate between a.startdate and a.enddate or a.startdate between startdate-1 and enddate+1 or a.enddate between startdate and enddate))) as enddate format=date9.
		from have a
	;
quit;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;The idea is simple: try to group the interval; while the implementaion is strenous. Good Luck!&lt;/P&gt;</description>
      <pubDate>Wed, 16 Sep 2015 17:16:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225893#M40598</guid>
      <dc:creator>Haikuo</dc:creator>
      <dc:date>2015-09-16T17:16:02Z</dc:date>
    </item>
    <item>
      <title>Re: Getting Consecutive Days</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225949#M40616</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Below is another pure PROC SQL approach. It uses a self-join twice to (detect earlier and later rows) and&amp;nbsp;enables two rows being&amp;nbsp;collapsed into one. However, it does not deal with collapsing three or more rows into one; not sure if that kind of scenario would happen in your data, based on the example you provided.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;PROC SQL;
  CREATE TABLE have (
    id        num, 
    startdate num format=date11., 
    enddate   num format=date11.);
QUIT;


PROC SQL;
INSERT INTO have
values (101, '15-Dec-2013'd, '15-Dec-2013'd)
values (101, '16-Dec-2013'd, '16-Dec-2013'd)
values (101, '28-Dec-2013'd, '28-Dec-2013'd)
values (101, '29-Dec-2013'd, '31-Dec-2013'd)
/* add some additional data for good measure ... */
/* note that there are 3 consecutive rows (1/15 to 1/28/2014) */
/* values (201, '15-Jan-2014'd, '17-Jan-2014'd) */
/* values (201, '18-Jan-2014'd, '26-Jan-2014'd) */
/* values (201, '27-Jan-2014'd, '28-Jan-2014'd) */
/* values (201, '01-Feb-2014'd, '01-Feb-2014'd) */
;
QUIT;


PROC SQL;
  CREATE TABLE want AS 
  SELECT id
       , startdate
       , coalesce(nextRow_enddate, enddate) format=date11. AS wanted_enddate
  /* subquery joins current row to earlier row and future row (if they exist) */
  FROM (SELECT aa.id
             , aa.startdate
             , aa.enddate
             , monotonic()   as seq_num
             , next.enddate  as nextRow_enddate
             , prior.enddate as priorRow_enddate
        FROM have as aa
        LEFT JOIN have as next
               ON next.id = aa.id
              AND next.startdate = aa.enddate+1
        LEFT JOIN have as prior
               ON prior.id = aa.id
              AND prior.enddate = aa.startdate-1
        WHERE priorRow_enddate IS NULL) as qry;
QUIT;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 16 Sep 2015 21:29:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Getting-Consecutive-Days/m-p/225949#M40616</guid>
      <dc:creator>hbi</dc:creator>
      <dc:date>2015-09-16T21:29:42Z</dc:date>
    </item>
  </channel>
</rss>

