我有一个设备表(dev)和device_date表(dev_data)。关系1:M
dev表:
| id |name |status |
|-----|-------|-------|
| 1 |a |111 |
|-----|-------|-------|
| 2 |b |123 |
|-----|-------|-------|
| ....|..... |.... |
dev_data表:
|id |dev_id |status |date |
|---|-------|--------|------------------------|
|1 |1 | 123 |2019-04-16T18:53:07.908Z|
|---|-------|--------|------------------------|
|2 |1 | 120 |2019-04-16T18:54:07.908Z|
|---|-------|--------|------------------------|
|3 |1 | 1207 |2019-04-16T18:55:07.908Z|
|---|-------|--------|------------------------|
|4 |2 | 123 |2019-04-16T18:53:08.908Z|
|---|-------|--------|------------------------|
|5 |2 | 121 |2019-04-16T18:54:08.908Z|
|---|-------|--------|------------------------|
|6 |2 | 127 |2019-04-16T18:55:08.908Z|
|...|.......|........|........................|
我需要选择所有dev并加入dev_data,但仅添加2条最后记录(按日期)
最终答复应如下所示:
status_calc_1
和status_calc_2
是dev和dev_data中status
之间的区别
status_calc_1 => status
与dev_data和dev的最后一行的差异
status_calc_2 => status
与dev_data和dev的最后一行的差异
|id |name |status_calc_1 | status_calc_2 |
|----|------|---------------|---------------|
|1 |a |1207-111 |120-111 |
|----|------|---------------|---------------|
|2 |b |127-123 |121-123 |
我尝试了这个:
select id, "name", status, max(dd.date) as last,
(select date from device_data p where p.dev_id = device.id and date < dd.date limit 1) as prelast
from device
inner join device_data dd on device.id = dd.dev_id
group by id, "name", status;
但出现错误:
ERROR: subquery uses ungrouped column "device.id" from outer query
和这个:
select id, "name", status, max(dd.date) as last, max(dd2.date) as prelast,
from device
inner join device_data dd on device.id = dd.dev_id
inner join device_data dd2 on device.id = dd2.dev_id and dd2.date < dd.date
group by id, "name", status;
我得到正确的最后2个dev_data,但是仍然不知道如何制作2列status_calc_1
和status_calc_2
status_calc_1 =最后一行dev_data.status-dev.status
status_calc_2 =前一行dev_data.status-dev.status
答案 0 :(得分:2)
您可以使用条件聚合:
select d.id, d.name, d.status,
max(dd.date) as last,
max(case when dd.seqnum = 2 then dd.date end) as prelast,
(max(case when dd.seqnum = 1 then dd.status end) - d.status) as status_calc_1,
(max(case when dd.seqnum = 2 then dd.status end) - d.status) as status_calc_2
from device d join
(select dd.*,
row_number() over (partition by dd.dev_id order by dd.date desc) as seqnum
from device_data dd
) dd
on d.id = dd.dev_id
where seqnum <= 2
group by d.id, d.name, d.status;