Reputation: 279
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
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
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