Victor Ronin
Victor Ronin

Reputation: 279

SQL. How to work/compare/find differences within different rows in the same table

I have a table which looks like this:

ID   Date      Size   Marked
1    2010-02-02    2        X
2    2002-02-02    1
1    2010-02-03    2        X
2    2010-02-03    3        
3    2010-02-03    4        X

And I have a code (PHP) which does following things: a) Calculate sum of sizes per day b) Find the difference between total for this day and last day. c) Find the sum of sizes for rows which became marked this day (the row with the same id wasn't marked yesterday).

As example, I will get following results:

Date        Total  DiffWithYesterday  MarkedThisDay
2010-02-02    3      0                  0
2010-02-03    9      6                  4

I have feeling that there is a way to write this in SQL. However I am quite weak in SQL, so I gave up after a day playing around inner joins, group by and embedded selects.

I would appreciate, if you give me some clues how to do that.

Oh.. And I am using MySQL.

Regards, Victor

Upvotes: 0

Views: 1759

Answers (2)

Craig
Craig

Reputation: 1337

Something like this works in SQL Server. I don't have MySQL to test but you can probably convert once you see the logic.

create table so (sodate datetime, sosize int, somarked varchar(1))

insert into so (sodate,sosize,somarked) values ('1-jan-2010',3,'X')
insert into so (sodate,sosize,somarked) values ('2-jan-2010',1,'X')
insert into so (sodate,sosize,somarked) values ('3-jan-2010',2,'X')
insert into so (sodate,sosize,somarked) values ('4-jan-2010',0,null)
insert into so (sodate,sosize,somarked) values ('5-jan-2010',2,null)
insert into so (sodate,sosize,somarked) values ('6-jan-2010',1,null)
insert into so (sodate,sosize,somarked) values ('6-jan-2010',4,null)
insert into so (sodate,sosize,somarked) values ('6-jan-2010',1,null)
insert into so (sodate,sosize,somarked) values ('7-jan-2010',3,'X')
insert into so (sodate,sosize,somarked) values ('8-jan-2010',3,'X')
insert into so (sodate,sosize,somarked) values ('9-jan-2010',2,null)
insert into so (sodate,sosize,somarked) values ('10-jan-2010',2,'X')
insert into so (sodate,sosize,somarked) values ('11-jan-2010',1,'X')
insert into so (sodate,sosize,somarked) values ('12-jan-2010',2,null)
insert into so (sodate,sosize,somarked) values ('13-jan-2010',3,'X')

select so.sodate
    ,sum(so.sosize) as Total
    ,isnull(sum(so.sosize),0) - isnull(min(so2.sosize),0) as DiffFromYesterday
    ,sum(case when so.somarked = 'X' then so.sosize end) as MarkedThisDay
from so
    left join (select so.sodate,sum(so.sosize) sosize from so group by sodate) so2 on dateadd(dd,1,so2.sodate) = so.sodate
group by so.sodate  

..and after installing mysql this seems to work there...

select so.sodate
    ,sum(so.sosize) as Total
    ,ifnull(sum(so.sosize),0) - ifnull(min(so2.sosize),0) as DiffFromYesterday
    ,sum(case when so.somarked = 'X' then so.sosize end) as MarkedThisDay
from so
    left join (select so.sodate,sum(so.sosize) sosize from so group by sodate) so2 on (so2.sodate + INTERVAL 1 day )= so.sodate
group by so.sodate  ;

Upvotes: 2

Bingy
Bingy

Reputation: 644

had fun with this one.

SELECT 
  today.date as Date, 
  today.total as Total, 
  (today.total - yesterday.total) as DiffWithYesterday  , 
  marked.total as MarkedThisDay
FROM
  (SELECT date, sum(size) as total
   FROM table_name
   GROUP BY date) today
LEFT JOIN 
  (SELECT date, sum(size) as total
   FROM table_name
   WHERE marked = 'X'
   GROUP BY date) marked ON today.date = marked.date
LEFT JOIN
  (SELECT (date + INTERVAL 1 day) as date, sum(size) as total
   FROM table_name
   GROUP BY date) yesterday ON today.date=yesterday.date

obviously, you will need to replace "table_name" with the name of your table

Upvotes: 2

Related Questions