Объединение в группы по периодам, полное объединение не работает должным образом - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть таблица продаж:

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

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

Спасибо, что уделили много времени на то, чтобы объяснить проблему.

1 Ответ

0 голосов
/ 26 апреля 2018

Если вы хотите, чтобы все строки в sales , стали первой таблицей в LEFT JOIN. Тем не менее, я думаю, что FULL JOIN должно работать, как это LEFT JOIN:

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.amount)
FROM sales s LEFT JOIN
     budget_periods bp
     ON s.date >= bp.start_date AND s.date <= bp.end_date
GROUP BY new_start_date, new_end_date;

Единственная причина, по которой вещи будут отфильтрованы из FULL JOIN, - это предложение WHERE, но у вас его нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...