所以让我描述一下问题:
-我有一个任务表,其中包含一个受让人列,一个创建列和一个已解决列
(创建和解决的都是时间戳)
+---------+----------+------------+------------+
| task_id | assignee | created | resolved |
+---------+----------+------------+------------+
| tsk1 | him | 2000-01-01 | 2018-01-03 |
+---------+----------+------------+------------+
-我有一个更改日志表,其中包含task_id,一个from列,一个to列和一个date列,该记录记录每次更改受让人的情况
+---------+----------+------------+------------+
| task_id | from | to | date |
+---------+----------+------------+------------+
| tsk1 | me | you | 2017-04-06 |
+---------+----------+------------+------------+
| tsk1 | you | him | 2017-04-08 |
+---------+----------+------------+------------+
我想选择一个表,该表显示间隔内从事任务的所有受让人的列表
+---------+----------+------------+------------+
| task_id | assignee | from | to |
+---------+----------+------------+------------+
| tsk1 | me | 2000-01-01 | 2017-04-06 |
+---------+----------+------------+------------+
| tsk1 | you | 2017-04-06 | 2017-04-08 |
+---------+----------+------------+------------+
| tsk1 | him | 2017-04-08 | 2018-01-03 |
+---------+----------+------------+------------+
我在first(/ last)行中遇到麻烦,其中from(/ to)应该设置为created(/ resolved),我不知道如何用来自两个不同表的数据创建列...
我尝试过按自己的方式选择它们,然后将所有行与union合并,但我认为这不是一个很好的解决方案...
答案 0 :(得分:1)
嗯。 。 。这比看起来要复杂。想法是使用lead()
获取下一个日期,但是您需要使用tasks
表中的信息来“增强”数据:
select task_id, to, date as fromdate,
coalesce(lead(date) over (partition by task_id order by date),
max(resolved) over (partition by task_id)
) as todate
from ((select task_id, to, date, null::timestamp
from log l
) union all
(select distint on (t.task_id) t.task_id, l.from, t.created, t.resolved
from task t join
log l
on t.task_id = l.task_id
order by t.task_id, l.date
)
) t;
答案 1 :(得分:0)
SELECT
l.task_id,
assignee_from as assignee,
COALESCE(
lag(assign_date) OVER (ORDER BY assign_date),
created
) as date_from,
assign_date as date_to
FROM
log l
JOIN
task t
ON l.task_id = t.task_id
UNION ALL
SELECT * FROM (
SELECT DISTINCT ON (l.task_id)
l.task_id, assignee_to, assign_date, resolved
FROM
log l
JOIN
task t
ON l.task_id = t.task_id
ORDER BY l.task_id, assign_date DESC
) s
ORDER BY task_id, date_from
UNION
包括两部分:日志部分,最后是任务表的最后一行。
第一部分使用LAG()
window function获取当前行的前一个日期。由于"me"
没有上一行,因此将产生一个NULL
值。因此,可以通过从created
表中获取task
日期来捕捉到这一点。
第二部分是获取最后一行:在这里,我通过DISTINCT
和ORDER BY assign_date DESC
获取日志的最后一行。所以我知道最后一个assignee_to
。其余部分与第一部分类似:从任务表获取resolved
值。
答案 2 :(得分:0)
多亏了S-Man和Gordon Linoff的回答,我才能够提出以下解决方案:
SELECT t.task_id,
t.item_from AS assignee,
COALESCE(lag(t.changelog_created) OVER (
PARTITION BY t.task_id ORDER BY t.changelog_created),
max(t.creationdate) OVER (PARTITION BY t.task_id)) AS fromdate,
t.changelog_created as todate
FROM ( SELECT ch.task_id,
ch.item_from,
ch.changelog_created,
NULL::timestamp without time zone AS creationdate
FROM changelog_generic_expanded_view ch
WHERE ch.field::text = 'assignee'::text
UNION ALL
( SELECT DISTINCT ON (t_1.id_task) t_1.id_task,
t_1.assigneekey,
t_1.resolutiondate,
t_1.creationdate
FROM task_jira t_1
ORDER BY t_1.id_task)) t;
注意:这是最终版本,因此名称有所不同,但是思路保持不变。
这基本上与Gordon Linoff的代码相同,但是我以相反的方向浏览changelog。
我使用UNION ALL的第二部分来生成最后一个受让人,而不是第一个(这是为了处理根本没有变更日志的情况,生成最后一个受让人而不涉及变更日志的情况)