Sql 从联接表中选择两个条目(1:m)

Sql 从联接表中选择两个条目(1:m),sql,postgresql,join,Sql,Postgresql,Join,我有一个设备表dev和设备日期表dev_数据。关系1:M 开发表: | id |name |status | |-----|-------|-------| | 1 |a |111 | |-----|-------|-------| | 2 |b |123 | |-----|-------|-------| | ....|..... |.... | dev_数据表: |id |dev_id |status |date

我有一个设备表dev和设备日期表dev_数据。关系1:M

开发表:

| id  |name   |status |
|-----|-------|-------|
| 1   |a      |111    |
|-----|-------|-------|
| 2   |b      |123    |
|-----|-------|-------|
| ....|.....  |....   |
dev_数据表:

|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_数据,但按日期仅添加2条最后记录

最终的响应应该如下所示:

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;
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;
状态计算1和状态计算2在开发和开发数据中的状态之间存在差异

status_calc_1=>dev_数据和dev的最后一行的状态差异

|id  |name  |status_calc_1  | status_calc_2 |
|----|------|---------------|---------------|
|1   |a     |1207-111       |120-111        |
|----|------|---------------|---------------|
|2   |b     |127-123        |121-123        |
status_calc_2=>与dev_数据和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;
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;
还有这个:

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;
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;
我得到了正确的最后两个dev_数据,但仍然不知道如何创建两列status_calc_1和status_calc_2

status_calc_1=最后一行dev_data.status-dev.status


status\u calc\u 2=上一行dev\u data.status-dev.status

您可以使用条件聚合:

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;

我不知道计算结果是什么。您的查询只返回日期。