我有一张销售表:
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。要计算我的end_date,预算期限“默认”为七天,因此比start_date晚六天。
所以,我将查询修改为FULL 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.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
但是,结果表与我有LEFT JOIN时的结果表相同。我该怎么做呢?
感谢您抽出时间阅读这么长时间解释问题。
答案 0 :(得分:0)
如果您想要 sales 中的所有行,请将其作为Child
中的第一个表。但是,我认为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
子句,但你没有。{/ p>