У меня есть таблица продаж:
SALES
|---------|-------------|-------------|
| order | ammount | date |
|---------|-------------|-------------|
| 001 | $2,000 | 2018-01-01 |
| 002 | $3,000 | 2018-01-01 |
| 003 | $1,500 | 2018-01-03 |
| 004 | $1,700 | 2018-01-04 |
| 005 | $1,800 | 2018-01-09 |
| 006 | $4,200 | 2018-01-11 |
|---------|-------------|-------------|
Кроме того, у меня есть таблица, которая группирует продажи по произвольным периодам времени:
BUDGET PERIODS
|---------|-------------|--------------|
| ID | start_date | end_date |
|---------|-------------|--------------|
| 1 | 2018-01-01 | 2018-01-02 | <- notice this is a 2 day period...
| 2 | 2018-01-03 | 2018-01-05 | <-- but this is 3 days
|---------|-------------|--------------|
Итак, мой запрос к таблице результатов выглядел так:
GROUPED SALES
|--------------|---------------|-----------------|
| start_date | end_date | ammount |
|--------------|---------------|-----------------|
| 2018-01-01 | 2018-01-02 | $5,000 |
| 2018-01-03 | 2018-01-05 | $3,200 |
|--------------|---------------|-----------------|
Я выполнил запрос следующим образом:
SELECT
bp.start_date,
bp.end_date,
SUM(s.ammount)
FROM
budget_periods bp
LEFT JOIN
sales s ON s.date >= bp.start_date AND s.date <= bp.end_date
GROUP BY
start_date,
end_date
Тогда все замечательно. НО, я заметил, что, конечно, некоторые продажи не включены, потому что они не в бюджетные периоды. Следовательно, я хочу включить их «где-то». Я решил, что это «где-то» будет неделей продажи (используя функцию обрезки недели в Postgres). Следовательно, мои сгруппированные продажи должны выглядеть следующим образом:
GROUPED SALES
|--------------|---------------|-----------------|
| start_date | end_date | ammount |
|--------------|---------------|-----------------|
| 2018-01-01 | 2018-01-02 | $5,000 |
| 2018-01-03 | 2018-01-05 | $3,200 |
| 2018-01-08 | 2018-01-14 | $6,000 |
|--------------|---------------|-----------------|
Обратите внимание, что если вы урежете до недели 2018-01-09 и 2018-01-11, будет показано 2018-01-08. Для расчета моей конечной даты бюджетный период «по умолчанию» равен семи дням, поэтому он на шесть дней позже начальной даты.
Итак, я изменил запрос в ПОЛНОЕ СОЕДИНЕНИЕ следующим образом:
SELECT
COALESCE(bp.start_date, DATE_TRUNC('WEEK', s.date)) AS new_start_date,
COALESCE(bp.end_date, DATE_TRUNC('WEEK', s.date) + INTERVAL '6 DAY') AS new_end_date,
SUM(s.ammount)
FROM
budget_periods bp
FULL JOIN
sales s ON s.date >= bp.start_date AND s.date <= bp.end_date
GROUP BY
new_start_date,
new_end_date
Но тогда таблица результатов такая же, как когда у меня было левое соединение. Как мне подойти к этому?
Спасибо, что уделили много времени на то, чтобы объяснить проблему.