2016-09-14 7 views
-1

У меня есть запрос, который я запускаю несколько раз за каждый день в диапазоне. Я хотел бы уменьшить это один запрос:MYSQL Group By Interval Of Days Sum Каждый день

SELECT SUM(amount) AS all_time_revenue 
FROM charges WHERE DATE(`charges`.`created_at`) <= '2015-03-01' 

Я бегу в проблему, пытается преобразовать это в одном запросе - я не могу GROUP BY «created_at», потому что я захватывая все обвинения до того и на дату. (Не только в эту дату). Не уверен, что это возможно, но я уверен, что здесь есть гений, который может его решить. Примечание: Было бы неплохо, если бы я смог вернуть myDate, а также сумму сумма для каждой строки.

Вот полный пример того, что я делаю:

$start_time = new DateTime('2016-08-01'); 
$end_time = new DateTime('2016-08-14'); 
$data = []; 
for ($start_time; $start_time < $end_time; $start_time = $start_time->modify('+1 day')) { 
    $date = $start_time->format("Y-m-d"); 

    $results = DB::SELECT("SELECT SUM(amount) AS all_time_revenue 
          FROM charges 
          WHERE `charges`.`created_at` <= ? AND `charges`.`sandbox`=0", 
          ", [$date]); 
    $data[$date] = $results[0]->all_time_revenue; 
} 

Так в идеале я хотел бы запустить один запрос, который может работать с диапазоном дат или одну датой и количеством дней интервала и иметь его выплюнуть строки, как:

row 1: ['2016-08-01', 4000.00] 
row 2: ['2016-08-02', 4500.00] 
... 
row 14:['2016-08-14', 15000.00] 
+2

См. Http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple-sql- query – Strawberry

+0

Не все понятно, что такое тип данных 'created_at' ... это DATE? DATETIME? И какой диапазон значений предоставляется для $ mydate? – spencer7593

+0

Спасибо, потому что я понятия не имел, о чем жаловалась @Strawberry. –

ответ

0

Я думаю, что следующий запрос представляет то, что вы ищете. Он работает на диапазон дат по мере необходимости. Это единственный запрос, который генерирует совокупную сумму (суммирует ее с даты начала, указанной в диапазоне дат). Если вы хотите, чтобы суммирование проводилось с эпохи, это также можно было сделать.

create table tt (dt date, i integer); 

insert into tt values("2016-01-01",1); 

insert into tt values("2016-01-02",1); 
insert into tt values("2016-01-02",2); 

insert into tt values("2016-01-03",1); 
insert into tt values("2016-01-03",2); 
insert into tt values("2016-01-03",3); 

insert into tt values("2016-01-04",1); 
insert into tt values("2016-01-04",2); 
insert into tt values("2016-01-04",3); 
insert into tt values("2016-01-04",4); 

insert into tt values("2016-01-05",1); 
insert into tt values("2016-01-05",2); 
insert into tt values("2016-01-05",3); 
insert into tt values("2016-01-05",4); 
insert into tt values("2016-01-05",5); 

insert into tt values("2016-01-06",1); 
insert into tt values("2016-01-06",2); 
insert into tt values("2016-01-06",3); 
insert into tt values("2016-01-06",4); 
insert into tt values("2016-01-06",5); 
insert into tt values("2016-01-06",6); 

set @csum := 0; 
select date_format(dt,'%Y-%m-%d') dt,@csum:[email protected]+i as csum 
from (
    select dt,sum(i) as i 
    from tt 
    where dt between date('2016-01-02') and date('2016-01-05') 
    group by dt 
) as t1 
order by 1; 

|   dt | csum | 
|------------|------| 
| 2016-01-02 | 3 | 
| 2016-01-03 | 9 | 
| 2016-01-04 | 19 | 
| 2016-01-05 | 34 | 

Если вы хотите получить кумулятивные суммы, начиная с эпохи ...

set @csum := 0; 
select date_format(dt,'%Y-%m-%d') dt,@csum:[email protected]+i as csum 
from (
    select dt,sum(i) as i 
    from tt 
    where dt<=date('2016-01-05') 
    group by dt 
) as t1 
where dt<=date('2016-01-05') and date('2016-01-05') 
order by 1; 

|   dt | csum | 
|------------|------| 
| 2016-01-01 | 1 | 
| 2016-01-02 | 4 | 
| 2016-01-03 | 10 | 
| 2016-01-04 | 20 | 
| 2016-01-05 | 35 | 
+0

Еще раз спасибо, но я считаю, что все еще немного. Учитывая данные выше и диапазон дат. 2016-01-03 -> 2016-01-05. Я хотел бы вернуть суммы следующим образом: '['2016-01-03' => 10, '2016-01-04' => 20, '2016-01-05' => 35]' –

+0

Я Думаю, я могу это сделать, разбив его на 2 вопроса. Например, для диапазона дат ** 2016-01-03 -> 2016-01-05 **: первый получит общие сборы до ** 2016-01-03 **. Второй будет использовать вашу технику суммарной суммы для ** 2016-01-04 - 2016-01-05 ** и использовать небольшой PHP для добавления правильных итогов. Это было бы намного более эффективным, чем то, как я делал это в больших диапазонах дат. –

+0

Если у вас есть зависимости, которые могут быть лучше удовлетворены, разбив их на два запроса, это нормально. Вы собираетесь вычислить сумму до 2016-01-03 с использованием первого запроса; затем используйте это значение в качестве начальной загрузки для вычисления совокупных сумм во втором запросе. Я думаю, вы идете в правильном направлении. – blackpen