How do I collapse contiguous Date Ranges in SQL?

Hi,
In the data below, I want to collapse the contiguous date ranges with the same value (3.7) into a single date range.  I have tried and tried to come up with something but am stuck.  Does anyone know how to accomplish?
DECLARE @Have TABLE(B DATE, E DATE, R DECIMAL(18, 1))
INSERT INTO @Have VALUES
('2014-08-22', '2014-12-31', 4.0)
, ('2015-01-01', '2015-03-29', 3.7) -- same value, contingious date ranges
, ('2015-03-30', '2015-03-31', 3.7) -- same value, contingious date ranges
, ('2015-04-01', '2015-09-30', 4.0)
SELECT * FROM @Have
DECLARE @Want TABLE(B DATE, E DATE, R DECIMAL(18, 1))
INSERT INTO @Want VALUES
('2014-08-22', '2014-12-31', 4.0)
, ('2015-01-01', '2015-03-31', 3.7) -- want to collapse into 1 date range
, ('2015-04-01', '2015-09-30', 4.0)
SELECT * FROM @Want
Thanks

Hi tballard,
The posts from Jingyang and Cooper would be perfect only in the case that there’s no date gap between your rows. In addition to their posts, if in any case there would be a gap, please refer my code below, which works in either case.
DECLARE @Have TABLE(B DATE, E DATE, R DECIMAL(18, 1))
INSERT INTO @Have VALUES
('2014-08-22', '2014-12-30', 3.7) --same value , date gap
, ('2015-01-01', '2015-03-29', 3.7) -- same value, contingious date ranges
, ('2015-03-30', '2015-03-31', 3.7) -- same value, contingious date ranges
, ('2015-04-01', '2015-09-27', 4.0) --same value, date gap
, ('2015-10-1', '2015-12-30', 4.0) --same value, date gap
;WITH CTE1 AS(
SELECT H1.B B1,H1.E E1,H1.R R1,H2.B B2,H2.E E2,ISNULL(H2.R,0) R2,ROW_NUMBER() OVER(ORDER BY H1.B) RN FROM @HAVE H1 LEFT JOIN @HAVE H2 ON DATEDIFF(DAY,H1.B,H2.E)=-1
CTE2 AS(
SELECT B1,E1,R1 FROM CTE1 WHERE R1 != R2
CTE3 AS(
SELECT B1,E1,RN,B2 FROM CTE1 WHERE R1=R2
CTE4 AS(
Select min(B2) B, Max(E1) E from (
SELECT B2,E1,RN-row_number() Over(Order by B1) groupByCol
FROM CTE3
) t
Group by groupByCol
SELECT
C2.B1,ISNULL(C4.E,C2.E1),C2.R1
FROM CTE2 C2 LEFT JOIN CTE4 C4 ON C2.B1=C4.B
If you have any question, feel free to let me know.
Best regards,
Eric Zhang

Similar Messages

  • Compute Date Range with SQL Statement

    I'm sure there is a way to do this in SQL, but I cannot figure it out. I can write a PL/SQL script to do it, but would prefer using a SQL Statement. My database is Oracle Database 10.2.0.4.0.
    I have a table that contains information such as the employee number, department id, and the effective date of when the person started in that department. There is data in another table that I want to update their department number in based on their effective date range. If I could figure out how to select the effective date range correctly, I can do the rest.
    I have data such as:
    EMP_ID DEPT_NO EFFECTIVE
    101 1000 1/15/2001
    101 1050 5/24/2005
    101 2010 6/8/2008
    101 1000 8/2/2010
    I want to write a SELECT statement that returns something like this where the END_DATE is the day before the EFFECTIVE date and the last record does not have an END_DATE because they are still assigned to that department. Also, the first record in the column, I don't want to select a DEPT_NO because the effective date logic was added in January 2001 so if a person started back in 1985 they could have switched departments zero to many times so I'm not going to update any data for that period:
    EMP_ID DEPT_NO EFFECTIVE END_DATE
    101 1/14/2001
    101 1000 1/15/2001 5/23/2005
    101 1050 5/24/2005 6/7/2008
    101 2010 6/8/2008 8/1/2010
    101 1000 8/2/2010
    Below is a script to create the data in a temp table that can be used to write a SELECT statement on. I have added two employee records with different dates.
    create table temp_activity
    (emp_id number(12),
    dept_no number(12),
    effective date);
    INSERT INTO temp_activity
    (EMP_ID,DEPT_NO,EFFECTIVE)
    VALUES
    (101,1000,to_date('1/15/2001','MM/DD/YYYY'))
    INSERT INTO temp_activity
    (EMP_ID,DEPT_NO,EFFECTIVE)
    VALUES
    (101,1050,to_date('5/24/2005','MM/DD/YYYY'))
    INSERT INTO temp_activity
    (EMP_ID,DEPT_NO,EFFECTIVE)
    VALUES
    (101,2010,to_date('6/8/2008','MM/DD/YYYY'))
    INSERT INTO temp_activity
    (EMP_ID,DEPT_NO,EFFECTIVE)
    VALUES
    (101,1000,to_date('8/2/2010','MM/DD/YYYY'))
    INSERT INTO temp_activity
    (EMP_ID,DEPT_NO,EFFECTIVE)
    VALUES
    (102,1040,to_date('1/15/2001','MM/DD/YYYY'))
    INSERT INTO temp_activity
    (EMP_ID,DEPT_NO,EFFECTIVE)
    VALUES
    (102,2000,to_date('6/16/2006','MM/DD/YYYY'))
    Any help is appreciated. This is probably easy, but I cannot get my brain wrapped around it.
    Thanks - mike

    select  emp_id,
            dept_no,
            effective,
            end_date
      from  (
              select  emp_id,
                      dept_no,
                      effective,
                      lead(effective) over(partition by emp_id order by effective) - 1 end_date,
                      row_number() over(partition by emp_id order by effective) rn
                from  temp_activity
             union all
              select  emp_id,
                      null dept_no,
                      null effective,
                      min(effective) - 1 end_date,
                      0 rn
                from  temp_activity
                group by emp_id
      order by emp_id,
               rn
        EMP_ID    DEPT_NO EFFECTIVE  END_DATE
           101                       01/14/2001
           101       1000 01/15/2001 05/23/2005
           101       1050 05/24/2005 06/07/2008
           101       2010 06/08/2008 08/01/2010
           101       1000 08/02/2010
           102                       01/14/2001
           102       1040 01/15/2001 06/15/2006
           102       2000 06/16/2006
    8 rows selected.
    SQL> SY.

  • How would you send a date-range parameter to a SQL sproc?

    Team,
    MY ENVIRONMENT
    SQL 2005, Crystal Reports for Visual Studio 2005
    MY PROBLEM
    I am authoring both a sproc and a report, so I have full control over the design. I am a SQL expert and also a Crystal 8.5 expert.
    I have done the Sproc-Report connection dozens of times.
    Please consider along with me the sequence of creating a report based on a parameterized stored procedure.
    My sproc header is shown here:
    CREATE Procedure dbo.usp_DocumentActivityReport(
         @Department NVARCHAR(50)      
       , @DateRange  NVARCHAR(50)
    ) AS
    SELECT Col1, Col2, Col3 FROM #TEMP
    MY THOUGHT PROCESS
    @DEPARTMENT is a string. That's easy.
    @DATERANGE is a DATE RANGE and I don't know how to get Crystal Reports to prompt for a date range, so I used a String parameter knowing I can parse a specially formatted string, and knowing that I can use a formula to compute the string.
    Step 1. Create the blank report, the {?Department} parameter, the {?CreationDateRange} report parameter, and the {@DateRangeText} conversion formula that converts {?CreationDateRange} to the specially formatted string.
    Step 2. Test the stored procedure.
    Tests pass; It returns data when I run it with values, with zero-length string values, and with NULL values.
    Step 3. Tie the report to the stored procedure.
    Adding the sproc directly creates two hard-wired, undeletable parameters, and returns data columns. That's no good because the user must supply the specially formatted string for the date range. So, I try using Add Command instead, with this syntax:
    {call "EXP_TEST"."dbo"."usp_CorroDocumentActivityReport" (N'{?Department}', N'{@DateRangeText}')}
    This code is accepted, but Add Command did not create any undeletable parameters at all. I guess that's OK.
    But the worst part is that it does not show any output columns with data either! AAARGH!
    Please assist with showing me the proper order to do these steps.
    BTW, here's the VB Syntax formula for {@DateRangeText}:
    Dim min As String
    dim max as String
    if HasLowerBound ({?CreationDateRange}) then
      min = ToText(Minimum({?CreationDateRange}),"MM/dd/yyyy")
    else
      max = ""
    end if
    if HasUpperBound ({?CreationDateRange}) then
      max = ToText(Maximum({?CreationDateRange}),"MM/dd/yyyy")
    else
      max = ""
    end if
    if IncludesLowerBound ({?CreationDateRange}) then
      min = "[" & min
    else
       if HasLowerBound ({?CreationDateRange}) then min = "(" & min
    end if
    if IncludesUpperBound ({?CreationDateRange}) then
        max = max & "]"
    else
       if HasUpperBound ({?CreationDateRange}) then max = max & ")"
    end if
    'formula = min & "..." & max
    formula = "(1/1/2009...3/1/2009)"
    sorry ... cross-posted per Amit

    Ludek,
    It sounds like you and The specified item was not found. think along the same lines! I have cross-posted for both of you now!
    Please see Simple Sproc Parameters question
    ~ Shaun

  • How can I set a date range for a Date/Time Field in LiveCycle ES2?

    I need to set a specific date range for a form set up in LiveCycle ES2. Cannot see where i allows me to do that without a code entered.

    Hi,
    You can't set a start and end date for the date/time field, the best you can do is validate the range after the user has selected it.
    An alternate is to make your own date / time field, like this sample http://adobelivecycledesignercookbookbybr001.blogspot.com.au/2013/05/an-alternative-date-p icker-for.html
    Regards
    Bruce

  • How to export user using date range

    Hia , i am using Oracle10g my object to export user (pibs) all tables in pibs have
    created_date column
    i wan to export user pibs using date range created_date between 01-jan-07 and 05-jan-07
    pls help me

    Check out the QUERY clause.
    http://download-east.oracle.com/docs/cd/B19306_01/server.102/b14215/exp_imp.htm#CEGFIAGE
    If you're using Datapump, check out Filtering during export operations.
    http://download-east.oracle.com/docs/cd/B19306_01/server.102/b14215/dp_export.htm#g1022624

  • How to convert milliseconds to date format in sql query

    Hi All,
    The following code is in java.     
    String yourmilliseconds = "1316673707162";**
    Date resultdate = new Date(Long.parseLong(yourmilliseconds));
    could you plese tell me how to convert milliseconds into date format in query and comparing with another date like(sysdate-3)

    Hello,
    http://stackoverflow.com/questions/3820179/convert-epoch-to-date-in-sqlplus-oracle
    Regards

  • Finding duplicates within a date range. SQL help please!!

    I have a table of records and I am trying to query the duplicate emails that appear within a given date range but cant figure it out.
    There records that it returns are not all duplicates withing the given date range.  HELP!!
    Here is my query.
    Thanks in advance.
    SELECT cybTrans.email, cybTrans.trans_id, cybTrans.product_number, cybTrans.*
    FROM cybTrans
    WHERE (((cybTrans.email) In (SELECT [email] FROM [cybTrans] As Tmp GROUP BY [email] HAVING Count(*)>1 ))
    AND ((cybTrans.product_number)='27')
    AND ((cybTrans.appsystemtime)>'03-01-2010')
    AND ((cybTrans.appsystemtime)<'03-05-2010')
    ORDER BY cybTrans.email;

    Yet another method...
    <cfset start_date = DateFormat('01/01/2007',
    'mm/dd/yyyy')>
    <cfset end_date = DateFormat('09/30/2009',
    'mm/dd/yyyy')>
    <cfset start_year = DatePart('yyyy', start_date)>
    <cfset end_year = DatePart('yyyy', end_date)>
    <cfset schoolyear_start = '09/01/'>
    <cfset schoolyear_end = '06/30/'>
    <cfset count = 0>
    <cfloop index="rec" from="#start_year#"
    to="#end_year#">
    <cfset tmp_start = DateFormat('#schoolyear_start##rec#',
    'mm/dd/yyyy')>
    <cfset tmp_end = DateFormat('#schoolyear_end##rec + 1#',
    'mm/dd/yyyy')>
    <cfif DateCompare(tmp_start,start_date) gt -1 and
    DateCompare(tmp_end, end_date) eq -1>
    <cfset count = count + 1>
    </cfif>
    </cfloop>
    <cfoutput>
    <br>There are #count# school year periods between
    #start_date# and #end_date#
    </cfoutput>

  • How to execute procedure returning data rows from sql plus

    Hi,
    I want to execute a stored procedure that returns data rows from sql plus. please let me know the syntax for the same.
    Thanks,
    YG

    user13065317 wrote:
    Even if i get the result set into the cursor, do i have to do normal fetch into all the coumn variables within a loop
    But suppose no of columns in my result set varies depending on a parameter to the stored procedure.
    Is there any straightforward way to retrieve all the data irrespective of no of columns in the result set.There is no such thing as a "+result set+". Oracle does not create a temporary data set in memory that contains the results of your query. What would happen if this result set is a million rows and is too large to fit into memory? Or there are a 100 clients each with a 100,000 row result set?
    This is not scalable. You will be severely limited in the number and sizes of these "+result sets+" that can be created in server memory.
    A cursor is in fact a "program" that is created by compiling the SQL source code that you provide. This source code is parsed and compiled into what Oracle calls an execution plan. This is nothing but a series of instructions that the cursor will execute in order to return the rows required.
    Thus the result set is actually the output from a cursor (a program). Likewise, bind variables are the input parameters to this program.
    All SQLs are parsed and compiled as cursors and stored in the SQL Shared Pool. Oracle gives you handle in return to use to address this cursor - bind values to it, execute it, describe the output structure returned by the cursor, and fetch the output from the cursor.
    On the client side, this handle is used in different ways. In PL/SQL alone, this cursor handle can be used as an implicit cursor (you do not even see or use the cursor handle in your PL/SQL code). Or you can use a PL/SQL cursor variable. Or a DBMS_SQL cursor variable. Or a reference cursor variable.
    Why so many different client structures for the very same SQL cursor handle returned by Oracle? Because to allow you, the programmer, all kinds of different features and flexibility.
    The ref cursor feature is the ability to pass this cursor handle around, not only between PL/SQL code, but also from PL/SQL to the actual client process (Java. VB, SQL*Plus, TOAD, etc).
    The primary thing to remember - irrespective of what the client calls this (e.g. ref cursor, SQL statement handle, etc), this all refers to the same SQL cursor in the Shared Pool. And that this SQL cursor is a program that outputs data, and not a result set in itself.

  • How to find last login date of a sql login?

    i want to disable the SQL Logins which are not logged in last 15 days. (I schedule a job every night to check and disable)
    For this 
    i want to find  last login date of all sql logins in an instance if the login didn't log in with in 15 days i want to disable them.
    In SYS.SYSLOGINS table we can see all the logins and 'isntname' tells us if it is SQL login or windows login. 
    but where to find the last login date of SQL log in ?
    Can any one help me?

    Hi HYDBA,
    If you use SQL Server 2005 or later, you can only get the current logon data using
    DMV likes:
    select
    max
    (login_time)as
    last_login_time, login_name
    from
    sys.dm_exec_sessions
    group
    by login_name;
    Related to your question there are two options:
    One is logon trigger,
    which is used to get current login time and login name comparing with the data from
    sys.dm_exec_sessions. If the current login time comparing with last login time is larger than 15 days, then prevent the current login.   
    Another one is to schedule a job, which is used to disable logon who’s current login time
    comparing with last login time is larger than 15 days.
    Hope it’s helpful for you.
    Regards, Amber zhang

  • How can we restrict the date range in the date picker

    While selecting any date a pop up date picker appears. In this date picker the users can select any future dates which can be 30-40 yrs ahead. How can customize this date picker so that the users are not allowed to slected date beyond certain range. ...??

    Hi user570596,
    I think there is no method to actually restrict the date picker popup, but you can use the ApexLib Framework (http://apexlib.sourceforge.net/) to define a min/max value for your date field. This will prevent the user from submitting the page when the date value is outside the defined range.
    See http://inside-apex.blogspot.com/2007/03/min-max-value-validation-in-browser.html
    for details.
    Patrick
    Check out my APEX-blog: http://inside-apex.blogspot.com
    Check out the ApexLib Framework: http://apexlib.sourceforge.net

  • [DIAdem] How can I trace a data range from a data channel?

    Hello,
    I am looking for a way to trace a range of data from a data channel using DIAdem script.
    Right now, I can only trace an entire data channel.
    Is it possible? I do not want to split a data channel in order to trace a part of it...
    Thank you.
    Regards

    Hello Tenanio,
    I believe this will answer your question:
    I am assuming in my code that you have a VIEW layout with a sheet called "Sheet 0" which has a 2D-graph in the top area (as can be seen from the screenshot below):
    Copy this Code into SCRIPT and run it, it should display the data the way you had described:
    View.Sheets(1).Cursor.Type = "Band"
    View.CoordinateWnd.Visible = TRUE
    View.ActiveSheet.Cursor.X1 = ChD(305,"Date_Mesure")
    View.ActiveSheet.Cursor.X2 = ChD(320,"Date_Mesure")
    View.Sheets("Sheet 0").Areas("Area : 1").DisplayObj.XScalingMode = "RangeScroll"
    call wndshow("View")
     Please let me know if this works for you and if you have any additional question.
           Otmar
    Otmar D. Foehner
    Business Development Manager
    DIAdem and Test Data Management
    National Instruments
    Austin, TX - USA
    "For an optimist the glass is half full, for a pessimist it's half empty, and for an engineer is twice bigger than necessary."

  • How can I use a date range in a list KPI value expression

    I am trying to create a series of status indicators for a document library in SharePoint 2010. I've made a status list for this. One of the desired KPI's is to show the percentage of documents that must be revised and approved within the next two
    months.
    I have a field which logs the next approval date (last approval date plus one year). In the standard form for the KPI I can set the value expression to return the percentage of documents to be reviewed between [Today] and a date that I fill
    in by hand (see image below). But I haven't yet been able to have the target date (two months from today) change dynamically. Is there a way to have the second date increment via a calculation here? Or do I need to use a recurring workflow to do this?
    Any help would be greatly appreciated - also if this post should be elsewhere. I am not a programmer, and just beginning to learn to make use of many of SharePoint's functions.
    Cheers,
    Russ Herald

    I'm not certain if you can use formulas here but if you can use the standard SharePoint Field Formulas you could try the following:
    For the second date could you just put: [Today]+60 to add 60 days to the current date
    Or to work with actual months you could possibly use: =DATE(YEAR([Today]),MONTH([Today])+2,DAY([Today])) to add exactly two months.
    Reference:
    https://msdn.microsoft.com/en-us/library/office/bb862071(v=office.14).aspx#sectionSection2

  • How can I get the data array from SQL Server Database?

    Hi,
    I can write a data array(2D)into a table of my SQL Server Database. The data array was writen to a column with image type. I know a data array is transformed a binary string when writing into database, but I dont know how to get the data array when I fetch the binary string from database.
    My question is:
    How to transform the binary string into data array? which vi's should I use? I have tried unflatten from string but failed.
    Any response is appriciated.
    Red

    happyxh0518 wrote:
    > I can write a data array(2D)into a table of my SQL Server Database.
    > The data array was writen to a column with image type. I know a data
    > array is transformed a binary string when writing into database, but I
    > dont know how to get the data array when I fetch the binary string
    > from database.
    >
    > My question is:
    > How to transform the binary string into data array? which vi's should
    > I use? I have tried unflatten from string but failed.
    In order to use Unflatten from string you first need to Flatten it
    before writing it. Also depending on the database driver, the returned
    data may actually not be binary but Hexadecimal encoded ASCII which you
    would first have to decode to binray.
    Rolf Kalbermatter
    Rolf Kalbermatter
    CIT Engineering Netherlands
    a division of Test & Measurement Solutions

  • How to get Portal page data in PL/SQL

    Hi,
    I have a oracle portal and i created a portlet in it. In its Pl/sql space i am writing a wrapper which calls a procedure in the database.
    I have dymaically created a html page through pl/sql.
    I am able to display the data in the form but my requriement is i have a text box in the form and i need to reteive that value in my Pl/SQL procedure to perform further operations.
    My problem is how do i retrieve a value present in the form in my Pl/Sql procedure
    Let me know for any concerns.
    Thanks
    Shubhadeep

    Perhaps, this is not a PL/SQL problem. This is your Oracle Portlet problem. You should see it's manual about the way to pass the data inside a procedure through form - i guess.
    Regards.
    Satyaki De.

  • How to read and store data from an SQL resultset

    I'm writing a program to create testing scripts. I have a working version of the program that takes data from a specific input file, processes it and then outputs it as a test file that is readable by this other system. That's all fine and dandy, but now I wish to extend my program so that it doesn't need the input file, it shoud run an SQL query on the database itself and output this, with some other data to the output file, I have been experimenting with some code below:
              ResultSet rset;
              rset = sql.sqlweight();
              while (rset.next()!= false)
                   System.out.println("I'm getting to this loop");
                   scanCode = rset.getString(1);
                   System.out.println(scanCode);
                   rset.next();
              }And method sqlweight looks like this:
         public static ResultSet sqlweight() throws SQLException
              Connection connectiona = DriverManager.getConnection(//hiding connection details);
              Statement stmtW = connectiona.createStatement();
              String sqlW = "Select distinct (selc_code) from selling_code, prod_orgu_link where selling_code.prod_id = prod_orgu_link.prod_id and prod_orgu_link.prou_prod_handling = 20";
              ResultSet rset = stmtW.executeQuery(sqlW);
              while (rset.next())
                   //System.out.println(rset.getString(1));
              //rset.close();
              //stmtW.close();
              //connectiona.close();
              return rset;
         }Code is a bit messy at the moment as I am constantly changing and adding things so excuse the formatting. I can't get it to enter the loop (hence the testing line I put in it). I am wondering what the best way would be to get the data held in the results set into my String variable scanCode. Thanks for any help or advice.

    I haven't thrown it away, it just looks like this now:
         public static ResultSet sqlweight() throws SQLException
              Connection connectiona = DriverManager.getConnection(//hiding connection details);
              Statement stmtW = connectiona.createStatement();
              String sqlW = "Select distinct (selc_code) from selling_code, prod_orgu_link where selling_code.prod_id = prod_orgu_link.prod_id and prod_orgu_link.prou_prod_handling = 20";
              ResultSet rset = stmtW.executeQuery(sqlW);
              return rset;     
         }

Maybe you are looking for