我有这样的结构表,表示状态变化。
+-----------+----------+----------------+-----------------+-------+
| record_id | group_id | attribute type | change date | value |
+-----------+----------+----------------+-----------------+-------+
| 1 | 1 | status | 4/16/2008 18:59 | s1 |
| 2 | 1 | details | 4/16/2008 18:59 | d5 |
| 3 | 1 | details | 8/7/2008 18:31 | d2 |
| 4 | 1 | details | 2/5/2009 22:15 | d1 |
| 5 | 1 | status | 4/3/2009 21:27 | s2 |
| 6 | 1 | details | 4/3/2009 21:27 | d7 |
| 7 | 2 | status | 4/3/2009 21:46 | s1 |
| 8 | 2 | details | 4/3/2009 21:46 | d1 |
+-----------+----------+----------------+-----------------+-------+
我想在两列中查询状态更改和状态详细信息更改,按时间戳分组(实际上任何状态更改都会更改细节,因此只有详细信息更改时间戳可用于更轻松的分组)并且状态传播到相关细节,像这样:
+-----------+-----------------+--------+---------+
| object id | change date | status | details |
+-----------+-----------------+--------+---------+
| 1 | 4/16/2008 18:59 | s1 | d5 |
| 1 | 8/7/2008 18:31 | s1 | d2 |
| 1 | 2/5/2009 22:15 | s1 | d1 |
| 1 | 4/3/2009 21:27 | s2 | d3 |
| 2 | 4/3/2009 21:46 | s1 | d1 |
+-----------+-----------------+--------+---------+
这是我开始使用的,但它留给我的是NULLs
SELECT history.record_id,
history.group_id,
history.changedate,
status_chages.value AS status,
history.value AS details
FROM history
LEFT JOIN (SELECT
history.group_id,
history.changedate,
history.value
FROM history
WHERE history.attribute_type = 'status') status_chages
ON status_chages.group_id = history.group_id AND
status_chages.changedate = history.changedate
WHERE history.attribute = 'details'
我首先想到的是用前一行数据填充NULL。
但有没有更好的方法来查询上面列出的结果?
答案 0 :(得分:2)
查询提供了所需的布局:
select
group_id,
change_date,
max(case attr_type when 'status' then value else null end) as status,
max(case attr_type when 'status' then null else value end) as detail
from history
group by 1, 2
order by 1, 2;
group_id | change_date | status | detail
----------+---------------------+--------+--------
1 | 2008-04-16 18:59:00 | s1 | d5
1 | 2008-08-07 18:31:00 | | d2
1 | 2009-02-05 22:15:00 | | d1
1 | 2009-04-03 21:27:00 | s2 | d7
2 | 2009-04-03 21:46:00 | s1 | d1
(5 rows)
您可以通过以下方式填充以前值的空值:
select
group_id,
change_date,
max(status) over (partition by group_id, part) status,
detail
from (
select *, count(status) over (partition by group_id order by change_date) part
from (
select
group_id,
change_date,
max(case attr_type when 'status' then value else null end) as status,
max(case attr_type when 'status' then null else value end) as detail
from history
group by 1, 2
) s
) s
order by 1, 2;
group_id | change_date | status | detail
----------+---------------------+--------+--------
1 | 2008-04-16 18:59:00 | s1 | d5
1 | 2008-08-07 18:31:00 | s1 | d2
1 | 2009-02-05 22:15:00 | s1 | d1
1 | 2009-04-03 21:27:00 | s2 | d7
2 | 2009-04-03 21:46:00 | s1 | d1
(5 rows)