【问题标题】:Generate multiple rows based on a single row containing a null value after a right join右连接后基于包含空值的单行生成多行
【发布时间】:2019-04-02 14:05:34
【问题描述】:

我有一个使用 SNMP 从多个设备检索数据的软件。 然后,软件会在表格中创建一条记录,其中包含开始轮询时间和结束轮询时间。

对于我们检索的每个 SNMP 表,我们将数据放在不同的表中。

在下面的模型中,有一个snmp表(FrequencyValue)。表格是这样的:

| Polls |                  |                  |
|-------|------------------|------------------|
| id    | start_time       | end_time         |
|-------|------------------|------------------|
| 1     | 2019-04-01T10:00 | 2019-04-01T10:10 |
| 2     | 2019-04-01T11:00 | 2019-04-01T11:10 |
| 3     | 2019-04-01T12:00 | 2019-04-01T12:10 |

| Devices    |
|------------|
| ip         |
|------------|
| 172.16.1.1 |

| FrequencyValue |         |                  |           |       |
|----------------|---------|------------------|-----------|-------|
|      device_ip | poll_id | timestamp        | frequency | value |
|----------------|---------|------------------|-----------|-------|
|     172.16.1.1 |       1 | 2019-04-01T10:02 |      1000 |    10 |
|     172.16.1.1 |       1 | 2019-04-01T10:02 |      2000 |    20 |
|                |         |                  |           |       |
|     172.16.1.1 |       3 | 2019-04-01T12:02 |      1000 |    10 |
|     172.16.1.1 |       3 | 2019-04-01T12:02 |      2000 |    20 |

问题出现在设备无法应答时,因为如表FrequencyValue所示,软件没有为该表创建记录。

问题:为了绘制 value 列每 frequency,我们想为每个 frequency 创建 n 行,将列 valuenull.

到目前为止,我们的查询如下所示:

select p.ip, coalesce(t.timestamp, p.start_time) as "time", t.frequency, t.value
from FrequencyValue as t
right join (
  select p.start_time, p.id, d.ip
  from Polls as p, Devices as d
) as p on (t.poll_id = p.id and t.device_ip = p.ip)

有输出:

|         ip | timestamp        | frequency | value |
|------------|------------------|-----------|-------|
| 172.16.1.1 | 2019-04-01T10:02 |      1000 |    10 |
| 172.16.1.1 | 2019-04-01T10:02 |      2000 |    20 |
|            |                  |           |       |
| 172.16.1.1 | 2019-04-01T11:00 |      null |  null |
|            |                  |           |       |
| 172.16.1.1 | 2019-04-01T12:02 |      1000 |    10 |
| 172.16.1.1 | 2019-04-01T12:02 |      2000 |    20 |

我们真正想要的是这样的:

|         ip | timestamp        | frequency | value |
|------------|------------------|-----------|-------|
| 172.16.1.1 | 2019-04-01T10:02 |      1000 |    10 |
| 172.16.1.1 | 2019-04-01T10:02 |      2000 |    20 |
|            |                  |           |       |
| 172.16.1.1 | 2019-04-01T11:00 |      1000 |  null |
| 172.16.1.1 | 2019-04-01T11:00 |      2000 |  null |
|            |                  |           |       |
| 172.16.1.1 | 2019-04-01T12:02 |      1000 |    10 |
| 172.16.1.1 | 2019-04-01T12:02 |      2000 |    20 |

我们尝试在查询中添加另一个右连接,但我们无法获得我们想要的结果。 频率未在其他地方定义,因此要检索可用的频率,我们可以select distinct 表中的频率。 数据库是 PostgreSQL。

【问题讨论】:

    标签: sql postgresql right-join


    【解决方案1】:

    使用cross join 生成行,然后使用left join 引入值:

    select d.ip, t.timestamp, f.frequency,  fv.value
    from devices d cross join
         (select distinct timestamp from frequencyvalue) t cross join
         (select distinct frequency from frequencyvalue) f left join
         frequencyvalue fv
         on fv.device_ip = d.ip and
            fv.timestamp = t.timestamp and
            fv.frequency = f.frequency;
    

    【讨论】:

      猜你喜欢
      • 2019-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 2023-03-03
      • 2014-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多