Solved

Counting num ber of days using tsql

Posted on 2014-12-12
5
78 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

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

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

This is basically a blog post I wrote recently. I've found that SARGability is poorly understood, and since many people don't read blogs, I figured I'd post it here as an article. SARGable is an adjective in SQL that means that an item can be fou…
After restoring a Microsoft SQL Server database (.bak) from backup or attaching .mdf file, you may run into "Error '15023' User or role already exists in the current database" when you use the "User Mapping" SQL Management Studio functionality to al…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

832 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