У меня есть таблица, которая выглядит так:
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
И у меня есть код (PHP), который выполняет следующие действия: a) Рассчитать сумму размеров в день b) Найдите разницу между итогом за этот день и последний день. c) Найдите сумму размеров для строк, которые стали отмечены в этот день (строка с тем же идентификатором не была отмечена вчера).
В качестве примера я получу следующие результаты:
Date Total DiffWithYesterday MarkedThisDay
2010-02-02 3 0 0
2010-02-03 9 6 4
У меня есть ощущение, что есть способ написать это в SQL. Однако я довольно слабый в SQL, поэтому я отказался после дня, играя вокруг внутренних объединений, группировки и встроенных выборов.
Буду признателен, если вы дадите мне несколько подсказок, как это сделать.
Ох.. И я использую MySQL.
С уважением, Виктор
получил удовольствие от этого.
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
очевидно, вам нужно будет заменить "table_name" на имя вашей таблицы
Что-то вроде этого работает в SQL Server. У меня нет MySQL для тестирования, но вы можете конвертировать, как только увидите логику.
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
.. и после установки mysql это, похоже, работает там...
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 ;