Solved

Counting num ber of days using tsql

Posted on 2014-12-12
5
79 Views
Last Modified: 2014-12-18
I have a transaction table that holds CID, status and transaction date. Status can be o, c , r.
A CID can go from o to c to r to c.

For each CID I want to find the duration it has been in o or r, and store it in a target table.

Please help me on how I can accomplish this using tsql, possibly without a cursor. I want to track number of days from o to c and r to c. If a CID is not in c status after being in o or r then it is considered to be in the same status till current date.

Sample data copied below and also attached as a worksheet.

Transaction table data:
1      o      12/1/2014
2      o      12/2/2014
3      o      12/3/2014   --3 o no c: 9 days till today
1      c      12/3/2014   --1 o to c: 12/1/2014 to 12/3/2014 = 1 day
1      r      12/4/2014  
2      c      12/4/2014   --2 o to c: 12/2/2014 to 12/4/2014 = 2 days
1      c      12/5/2014   --1 r to c: 12/4/2014  to 12/5/2014 = 1 day
1      r      12/10/2014 --1 r no c: 12/10/2014 to today = 2 days


Target table: has one row per CID+status
CID      status      DurationInDays
1      o             2
1      r              3  (1+2)
2      o              2
3      o              9


Calculate-duration.xls

Thank you for your help.
0
Comment
Question by:patd1
  • 2
  • 2
5 Comments
 
LVL 48

Expert Comment

by:PortletPaul
ID: 40497304
I see you have chosen SQL 2008 as the topic but is that the version you actually use?
in particular do you use SQL 2012 or later?

Is there s unique ID for each row in this table?
What is the table's name.?
0
 
LVL 32

Accepted Solution

by:
bhess1 earned 500 total points
ID: 40497331
Your data source must have uniquely identifiable rows for any such calculation to work.  For my work, I created and populated a simple temp table:

CREATE TABLE #tt (
    CID int NOT NULL,
    status char NULL,
    transdate datetime,
    seq int IDENTITY(1, 1)
    )

INSERT INTO #tt (cid, status, transdate) VALUES (1, 'o', '12/1/2014')
INSERT INTO #tt (cid, status, transdate) VALUES (2, 'o', '12/2/2014')
INSERT INTO #tt (cid, status, transdate) VALUES (3, 'o', '12/3/2014')
INSERT INTO #tt (cid, status, transdate) VALUES (1, 'c', '12/3/2014')
INSERT INTO #tt (cid, status, transdate) VALUES (1, 'r', '12/4/2014')
INSERT INTO #tt (cid, status, transdate) VALUES (2, 'c', '12/4/2014')
INSERT INTO #tt (cid, status, transdate) VALUES (1, 'c', '12/5/2014')
INSERT INTO #tt (cid, status, transdate) VALUES (1, 'r', '12/10/2014')

Open in new window


This method worked well to get your data out in the form you needed.

;WITH tf AS (
    SELECT 
        CID, 
        transdate,
        MAX(seq) AS seq,
        ISNULL(
            (
                SELECT MIN(transdate) 
                FROM #tt AS tX 
                WHERE tX.CID = #tt.CID 
                    AND tX.transdate > #tt.transdate
                ),
                CONVERT(varchar(10), CURRENT_TIMESTAMP, 101)
           ) AS nextDt
    FROM #tt
    GROUP BY cid, 
        transdate
	)

SELECT 
    tf.CID,
    status,
    SUM(DATEDIFF(DAY, tf.transdate, tf.nextDt)) AS durationInDays
FROM tf
INNER JOIN #tt AS t
    ON tf.CID = t.CID
    AND tf.seq = t.seq
WHERE t.status IN ('o', 'r')
GROUP BY tf.CID,
    status
ORDER BY
    tf.CID,
    status

Open in new window

0
 

Author Comment

by:patd1
ID: 40500406
Thank You bhess1. That seems to be working. Can you please explain the logic in simple words so I can understand.

Thanks a lot again.
0
 

Author Closing Comment

by:patd1
ID: 40507298
Thank You.
0
 
LVL 32

Expert Comment

by:bhess1
ID: 40507543
The WITH statement creates a virtual table consisting of (1) The CID, Transaction date, the latest transaction ID for that CID/Transaction date, and the next date a transaction with that CID occurs on, or the current date if there is no other record with that CID on a later date.

The output of the WITH statement is essentially another table. So we join that output back to the original source table by CID and Seq, and use the pair of dates in the WITH table to calculate the duration of the activity.
0

Featured Post

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I have written a PowerShell script to "walk" the security structure of each SQL instance to find:         Each Login (Windows or SQL)             * Its Server Roles             * Every database to which the login is mapped             * The associated "Database User" for this …
How to leverage one TLS certificate to encrypt Microsoft SQL traffic and Remote Desktop Services, versus creating multiple tickets for the same server.
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question