SQL To find difference between multiple rows

3.9k Views Asked by At

I have a table containing multiple records for different transactions i.e.

ID  Date         REF
1   01/09/2008   A
1   11/09/2008   A
1   01/10/2008   A
2   01/09/2008   A
2   01/10/2008   A
2   01/11/2008   B
2   01/12/2008   B

and I'm looking to summarise the data so that I have the average days for each id and ref... i.e.

ID  Ref    Avg_Days
1   A      15
2   A      30
2   B      30

Thanks in advance if anyone can help

3

There are 3 best solutions below

1
Quassnoi On BEST ANSWER

Average day difference is a SUM of differences divided by COUNT(*)

SUM of differences is in fact difference between MIN and MAX:

SELECT  id, ref, DATEDIFF(day, MIN(date), MAX(date)) / NULLIF(COUNT(*) - 1, 0)
FROM    mytable
GROUP BY
        id, ref
0
Chris Klepeis On

Something like this... not really sure how this info will help you with anything though.... need more info as to what your trying to average the days for.

SELECT ID, REF, AVG(DATEPART(day, [Date]))
FROM dbo.Table1
GROUP BY ID, REF

Reference: AVG, DATEPART

0
Adriaan Stander On

Using sql server 2005 try this.

DECLARE @Table TABLE(
        ID INT,
        Date DATETIME,
        Ref VARCHAR(MAX)
)

INSERT INTO @Table (ID,Date,Ref) SELECT 1, '01 Sep 2008', 'A'
INSERT INTO @Table (ID,Date,Ref) SELECT 1, '11 Sep 2008', 'A'
INSERT INTO @Table (ID,Date,Ref) SELECT 1, '01 Oct 2008', 'A'
INSERT INTO @Table (ID,Date,Ref) SELECT 2, '01 Sep 2008', 'A'
INSERT INTO @Table (ID,Date,Ref) SELECT 2, '01 Oct 2008', 'A'
INSERT INTO @Table (ID,Date,Ref) SELECT 2, '01 Nov 2008', 'B'
INSERT INTO @Table (ID,Date,Ref) SELECT 2, '01 Dec 2008', 'B'


;WITH Ordered AS (
    SELECT  ID,
            Ref,
            Date,
            ROW_NUMBER() OVER (PARTITION BY ID, Ref  ORDER BY Date) SubNumber
    FROM    @Table t
)
SELECT  Ordered.ID,
        Ordered.Ref,
        AVG(DATEDIFF(dd, Ordered.Date, OrderedNext.Date)) AVG_Days
FROM    Ordered INNER JOIN
        Ordered OrderedNext ON  Ordered.ID = OrderedNext.ID
                            AND Ordered.Ref = OrderedNext.Ref
                            AND Ordered.SubNumber + 1 = OrderedNext.SubNumber
GROUP BY Ordered.ID,
        Ordered.Ref

Also have a look at it mathematically:

Let say

([X(1)-X(0)] + [X(2)-X(1)] + [X(3)-X(2)] + ... + [X(n-1)-X(n-2)] + [X(n)-X(n-1)]) / (n-1).

expand the top part as

-X(0) + X(1) - X(1) + X(2) - X(2) + X(3) - ... - X(n-2) + X(n-1) - X(n-1) + X(n)

whcih end up as -X(0) + X(n)

so we have [X(n) - X(0)] / (n - 1)

so take (MAX - MIN) / (Count - 1) for count > 1