行值到列标题

Row value into column headings

我有一个readingstable。它被定义为:

   Column   |            Type             | Collation | Nullable | Default
------------+-----------------------------+-----------+----------+---------
 created_at | timestamp without time zone |           | not null |
 device     | character varying(25)       |           | not null |
 type       | character varying(25)       |           | not null |
 value      | numeric                     |           | not null |

它有这样的数据:

     created_at      |  device   |    type     |    value
---------------------+-----------+-------------+-------------
 2021-03-16 07:46:47 | 465125783 | temperature |        36.5
 2021-03-16 07:51:48 | 465125783 | temperature | 36.40000153
 2021-03-16 07:52:47 | 465125783 | temperature | 36.40000153
 2021-03-16 07:53:47 | 465125783 | temperature | 36.29999924
 2021-03-24 17:53:47 | 123456789 | pressure    |          79
 2021-03-24 17:54:48 | 123456789 | pressure    |          77
 2021-03-28 05:38:48 | 123456789 | flow        |          12
 2021-03-28 05:45:48 | 123456789 | flow        |          14
 2021-03-28 05:49:47 | 123456789 | pressure    |          65
 2021-03-28 05:50:47 | 123456789 | flow        |          32
 2021-03-28 05:51:47 | 123456789 | flow        |          40

我正在尝试为指定设备编写一个查询,我将 type 中的每个唯一值都变成一个标题,并计算出 每日平均值 value 仅过去两周 (time-period 来自 now())。

所以基本上,我将查询传递给设备 ID,然后得到:

   date     |  device   | pressure | flow
------------+-----------+----------+-------
 2021-03-28 | 123456789 | 65       | 24.5
 2021-03-24 | 123456789 | 78       | 0

注意 desc sort 不再需要日期和时间信息,只需要日期。

我创建了一个 db-fiddle here。从行中获取列标题的概念我以前没有做过。

这是条件聚合,在 Postgres 中使用 FILTER:

select created_at::date, device,
       avg(value) filter (where type = 'pressure') as pressure,
       avg(value) filter (where type = 'flow') as flow
from readings
group by created_at::date, device;

注意:这将缺失值表示为 NULL 而不是 0,这对我来说很有意义。如果你想要0,你可以使用COALESCE()

Here 是 db-fiddle.