【问题标题】:Chained join not filtering as expected链式连接未按预期过滤
【发布时间】:2020-12-15 20:16:14
【问题描述】:

我在这里有一个相关的问题:

Generate month data series with null months included?

当我发帖时,我忽略了第二次加入,认为这是微不足道的,不会影响我的问题 - 我错了。

SELECT TO_CHAR(activity_tasks.start_date, 'MON') AS month,
EXTRACT(MONTH FROM activity_tasks.start_date) AS month_num,
SUM(cost_planned) FILTER (WHERE activity_tasks.aasm_state IN ('open', 'planned' ) )  AS planned,
SUM(cost_actual) FILTER (WHERE activity_tasks.aasm_state IN ('closed' ) ) AS actual
FROM "activity_tasks"
INNER JOIN "activities"."id" = "activity_tasks"."activity_id"
WHERE "activities"."type" = 'My Type' AND activity_tasks.start_date >= '2020-01-01' AND activity_tasks.start_date <= '2020-12-31'
GROUP BY month, month_num
ORDER BY month_num

这让我很感动:

+-------+-----------+---------+--------+
| month | month_num | planned | actual |
+-------+-----------+---------+--------+
| NOV   | 11        | NULL    | 123    |
| DEC   | 12        | 500     | NULL   |
+-------+-----------+---------+--------+

接受的相关答案让我尝试了各种修改,例如添加:

LEFT JOIN activities a
ON a.id = t.activity_id AND a.type = 'My Type'

导致(不只是过滤掉My Type):

+-------+-----------+---------+--------+
| month | month_num | planned | actual |
+-------+-----------+---------+--------+
| JAN   | 1         | NULL    | NULL   |
| FEB   | 2         | NULL    | NULL   |
| MAR   | 3         | NULL    | NULL   |
| APR   | 4         | NULL    | NULL   |
| MAY   | 5         | NULL    | NULL   |
| JUN   | 6         | NULL    | NULL   |
| JUL   | 7         | NULL    | NULL   |
| AUG   | 8         | NULL    | NULL   |
| SEP   | 9         | NULL    | NULL   |
| OCT   | 10        | 0       | 0      |
| NOV   | 11        | 125     | 123    |
| DEC   | 12        | 1414    | 0      |
+-------+-----------+---------+--------+

试过这个:

ON a.id = t.activity_id
WHERE a.type = 'My Type'

这让我得到了正确的过滤结果,但我又丢失了过滤结果:

+-------+-----------+---------+--------+
| month | month_num | planned | actual |
+-------+-----------+---------+--------+
| NOV   | 11        | NULL    | 123    |
| DEC   | 12        | 500     | NULL   |
+-------+-----------+---------+--------+

我正在寻找这个 - 带有“空”月份的过滤任务:

+-------+-----------+---------+--------+
| month | month_num | planned | actual |
+-------+-----------+---------+--------+
| JAN   | 1         | NULL    | NULL   |
| FEB   | 2         | NULL    | NULL   |
| MAR   | 3         | NULL    | NULL   |
| APR   | 4         | NULL    | NULL   |
| MAY   | 5         | NULL    | NULL   |
| JUN   | 6         | NULL    | NULL   |
| JUL   | 7         | NULL    | NULL   |
| AUG   | 8         | NULL    | NULL   |
| SEP   | 9         | NULL    | NULL   |
| OCT   | 10        | NULL    | NULL   |
| NOV   | 11        | NULL    | 123    |
| DEC   | 12        | 500     | NULL   |
+-------+-----------+---------+--------+

我已经为第二次加入尝试了所有类型的 JOINS。不确定我在这里缺少什么。

【问题讨论】:

  • 你能添加你真正想要的结果吗?
  • 抱歉 - 我通常会重新阅读以确保我已经明确提出了具体问题。

标签: sql postgresql join


【解决方案1】:

意识到我需要这样的子选择:

SELECT 
  UPPER(TO_CHAR(d.start_date, 'mon')) AS month,
  EXTRACT(MONTH FROM d.start_date) AS month_num,
  SUM(t.cost_planned) FILTER (WHERE t.aasm_state IN ('open', 'planned' ) ) AS planned,
  SUM(t.cost_actual)  FILTER (WHERE t.aasm_state = 'closed') AS actual
FROM GENERATE_SERIES('2020-01-01'::date, '2020-12-01'::date, '1 month') d(start_date)
LEFT JOIN
(
SELECT t.*
FROM activity_tasks t
LEFT JOIN activities a
ON a.id = t.activity_id
WHERE a.type = 'My Type'
) AS t ON t.start_date >= d.start_date and t.start_date < d.start_date + '1 month'::interval
GROUP BY d.start_date
ORDER BY d.start_date

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 2014-05-15
    相关资源
    最近更新 更多