右连接后根据包含空值的单行生成多行
Generate multiple rows based on a single row containing a null value after a right join
我有一个软件可以使用 SNMP 从多个设备检索数据。
然后,软件会在 table 中创建一条记录,其中包含开始轮询时间和结束轮询时间。
对于我们检索的每个 SNMP table,我们将数据放在不同的 table 中。
在下面的模型中,有一个 snmp table (FrequencyValue)。 table 是这样的:
| 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 |
当设备无法应答时就会出现问题,因为如 table FrequencyValue
所示,软件没有为该 table 创建记录。
问题: 为了绘制每个 frequency
列 value
的图形,我们想为每个 n
行创建 frequency
将有列 value
到 null
.
到目前为止,我们的查询如下所示:
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
table 中的频率。
数据库是 PostgreSQL。
使用 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;
我有一个软件可以使用 SNMP 从多个设备检索数据。 然后,软件会在 table 中创建一条记录,其中包含开始轮询时间和结束轮询时间。
对于我们检索的每个 SNMP table,我们将数据放在不同的 table 中。
在下面的模型中,有一个 snmp table (FrequencyValue)。 table 是这样的:
| 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 |
当设备无法应答时就会出现问题,因为如 table FrequencyValue
所示,软件没有为该 table 创建记录。
问题: 为了绘制每个 frequency
列 value
的图形,我们想为每个 n
行创建 frequency
将有列 value
到 null
.
到目前为止,我们的查询如下所示:
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
table 中的频率。
数据库是 PostgreSQL。
使用 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;