MySQL объединяет одну и ту же таблицу несколько раз с группой - PullRequest
0 голосов
/ 28 мая 2018

у меня есть таблица products (id, name, price, ...) и productStats (productId, time, unitsSold, unitsReserved, ...).

В productStats у нас есть строка для каждой минуты и все необходимые совокупные значения для этой конкретной минуты.Если нам нужно получить статистику за один период, это нормально:

select 
    id,
    name,
    SUM(lastDay.unitsSold) as latDayUnitsSold,
from `products`

left join 
    `productStats` as `lastDay` 
    on `products`.`id` = `lastDay`.`productId` 
    and `lastDay`.`time` between '2018-05-27 00:00:00' and '2018-05-28 00:00:00'

group by `products`.`id`

Но мы столкнулись с ошибкой (неправильные значения), когда мы хотим получить агрегированные значения для нескольких периодов одновременно:

select 
    id,
    name,
    SUM(lastDay.unitsSold) as latDayUnitsSold,
    SUM(lastMonth.unitsSold) as latMonthUnitsSold,
    SUM(lastYear.unitsSold) as latYearUnitsSold,
from `products`

left join 
    `productStats` as `lastDay` 
    on `products`.`id` = `lastDay`.`productId` 
    and `lastDay`.`time` between '2018-05-27 00:00:00' and '2018-05-28 00:00:00'

left join 
    `productStats` as `lastMonth` 
    on `products`.`id` = `lastMonth`.`productId` 
    and `lastDay`.`time` between '2018-04-28 00:00:00' and '2018-05-28 00:00:00'

left join 
    `productStats` as `lastYear` 
    on `products`.`id` = `lastYear`.`productId` 
    and `lastDay`.`time` between '2017-05-28 00:00:00' and '2018-05-28 00:00:00'

group by `products`.`id`

Как мы можем присоединиться к одной и той же таблице несколько раз, но с разными диапазонами даты и времени и иметь отдельный столбец суммы для каждого из них?

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

Вы можете использовать условное агрегирование для другого временного диапазона, используя одну операцию объединения

SELECT 
    p.id,
    p.name,
    SUM(CASE WHEN `lastDay`.`time` BETWEEN '2018-05-27 00:00:00' AND '2018-05-28 00:00:00' THEN lastDay.unitsSold ELSE 0 END) AS latDayUnitsSold,
    SUM(CASE WHEN `lastDay`.`time` BETWEEN '2018-04-28 00:00:00' AND '2018-05-28 00:00:00' THEN lastDay.unitsSold ELSE 0 END) AS latMonthUnitsSold,
    SUM(lastDay.unitsSold) AS latYearUnitsSold,
FROM  `products` p
LEFT JOIN
    `productStats` AS `lastDay` 
    ON p.`id` = `lastDay`.`productId` 
    AND `lastDay`.`time` BETWEEN '2017-05-28 00:00:00' AND '2018-05-28 00:00:00'
GROUP BY p.id, p.name
0 голосов
/ 28 мая 2018

Попробуйте добавить все различные условия в одну таблицу соединений, используя OR

select 
    id,
    name,
    SUM(lastDay.unitsSold) as latDayUnitsSold,
    SUM(lastMonth.unitsSold) as latMonthUnitsSold,
    SUM(lastYear.unitsSold) as latYearUnitsSold,
from `products`

left join 
    `productStats` as `lastDay` 
    on `products`.`id` = `lastDay`.`productId` 
    and 
    (
     `lastDay`.`time` between '2018-05-27 00:00:00' and '2018-05-28 00:00:00'
      OR
     `lastDay`.`time` between '2018-04-28 00:00:00' and '2018-05-28 00:00:00'
      OR 
      `lastDay`.`time` between '2017-05-28 00:00:00' and '2018-05-28 00:00:00'
    )
group by `products`.`id`
...