Ale*_*son 5 postgresql join datetime sum coalesce
我有两个表 - 一个标题为“计划约束”的表,其中包含“sot_allowed”时间间隔,另一个标题为“计划”,其中包含“sot_contribution”时间间隔。
以下是两个表的架构(为便于阅读而进行了编辑):
Table "public.planning_constraints"
Column | Type | Modifiers
-------------+--------------------------+-------------------------------
start_time | timestamp with time zone |
end_time | timestamp with time zone |
sot_allowed | interval |
Table "public.planning"
Column | Type | Modifiers
------------------+--------------------------+----------------------------
start_time | timestamp with time zone |
end_time | timestamp with time zone |
sot_contribution | interval |
Run Code Online (Sandbox Code Playgroud)
我可以分别查询它们并生成我想要的总数。“planning_constraints”表的查询是:
SELECT
date_trunc('day', start_time - INTERVAL '18 hours')::date AS planning_day,
sum(sot_allowed) AS minutes_allowed
FROM planning_constraints
WHERE start_time>='2016-11-26 18:00:00+00' AND start_time<'2016-12-03 18:00:00+00' AND comment like '6%'
GROUP BY planning_day
ORDER BY planning_day;
Run Code Online (Sandbox Code Playgroud)
它产生:
planning_day | minutes_allowed
--------------+-----------------
2016-11-26 | 01:24:00
2016-11-27 | 01:38:00
2016-11-28 | 01:29:00
2016-11-29 | 01:43:00
2016-11-30 | 01:32:00
2016-12-01 | 01:41:00
2016-12-02 | 01:43:00
(7 rows)
Run Code Online (Sandbox Code Playgroud)
“计划”表的查询是:
SELECT
date_trunc('day', start_time - INTERVAL '18 hours')::date AS planning_day,
sum(sot_contribution) AS minutes_planned
FROM planning
WHERE start_time>='2016-11-26 18:00:00' AND start_time<'2016-12-03 18:00:00+00'
GROUP BY planning_day
ORDER BY planning_day;
Run Code Online (Sandbox Code Playgroud)
它产生:
planning_day | minutes_planned
--------------+-----------------
2016-11-26 | 01:19:12
2016-11-27 | 01:38:23
2016-11-28 | 01:27:36
2016-11-29 | 01:40:39
2016-11-30 | 01:27:16
2016-12-01 | 01:38:28
2016-12-02 | 01:42:50
(7 rows)
Run Code Online (Sandbox Code Playgroud)
我想在相邻列中显示这些查询的结果,以及它们之间的差异。这是我这样做的尝试:
SELECT
date_trunc('day', c.start_time - INTERVAL '18 hours')::date AS planning_day,
sum(c.sot_allowed) AS minutes_allowed,
sum(p.sot_contribution) AS minutes_planned,
(sum(c.sot_allowed) - sum(p.sot_contribution)) AS diff
FROM planning_constraints c, planning p
WHERE c.start_time>='2016-11-26 18:00:00+00' AND c.start_time<'2016-12-03 18:00:00+00' AND c.comment like '6%'
AND p.start_time>='2016-11-26 18:00:00' AND p.start_time<'2016-12-03 18:00:00+00'
GROUP BY planning_day
ORDER BY planning_day;
Run Code Online (Sandbox Code Playgroud)
它产生:
planning_day | minutes_allowed | minutes_planned | diff
--------------+-----------------+-----------------+-----------
2016-11-26 | 576:48:00 | 43:37:36 | 533:10:24
2016-11-27 | 672:56:00 | 43:37:36 | 629:18:24
2016-11-28 | 611:08:00 | 43:37:36 | 567:30:24
2016-11-29 | 707:16:00 | 43:37:36 | 663:38:24
2016-11-30 | 631:44:00 | 43:37:36 | 588:06:24
2016-12-01 | 693:32:00 | 43:37:36 | 649:54:24
2016-12-02 | 707:16:00 | 43:37:36 | 663:38:24
(7 rows)
Run Code Online (Sandbox Code Playgroud)
'minutes_allowed' 和 'minutes_planned' 列没有提供正确的值。我觉得我在这里遗漏了一些小东西,但是,我一直无法找到解决方案。
您基本上是在构建两个表,然后必须将它们连接到日期列上。在您的查询中,您错过了连接条件。
解决此问题的一种明确方法是将两个结果集构建为 CTE(带查询):
WITH pc AS (SELECT planning_day, sum(sot_contribution) AS minutes_planned
FROM planning_constraints
...),
p AS (SELECT planning_day, sum(sot_allowed) AS minutes_allowed
FROM planning
...)
SELECT planning_day,
COALESCE(minutes_allowed, interval '0 minute') AS allowed,
COALESCE(minutes_planned, interval '0 minute') AS planned,
COALESCE(minutes_allowed, interval '0 minute') -
COALESCE(minutes_planned, interval '0 minute') AS diff
FROM pc FULL OUTER JOIN p USING (planning_day)
ORDER BY planning_day;
Run Code Online (Sandbox Code Playgroud)
FULL OUTER JOIN意味着如果在任何一个结果集中指定了一天,那一天就会有一行。如果这不是您想要的,请弄清楚您需要哪种类型的连接。
笔记:
planning_day不需要是COALESCEd,因为该USING条款会处理这个问题GROUP BY在外部查询中使用 a ,因为planning_day这已经是两个源表的键ORDER BY可以从两个子查询现在删除| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |