如何确保 ResultSet 包含 "missing" 观察的行
How to ensure that a ResultSet includes rows for "missing" observations
我有一个结果集 table 如下所示:
+------------+--------------------+--------------------+---------+-----------------------+
| test_date | upload_kbps | download_kbps | latency | network_operator_name |
+------------+--------------------+--------------------+---------+-----------------------+
| 2017-04-02 | 19.12741903076923 | 44.614721153846155 | 32.1250 | Alcatel |
| 2017-03-31 | 18.30683616557377 | 44.294387978142076 | 34.7432 | Alcatel |
| 2017-03-31 | 20.643555595555555 | 50.99801587301587 | 32.1640 | Vodafone |
我想修改 ResultSet 以供进一步使用,同时我将一行添加到 ResultSet 中,如下所示:
+------------+--------------------+--------------------+---------+-----------------------+
| test_date | upload_kbps | download_kbps | latency | network_operator_name |
+------------+--------------------+--------------------+---------+-----------------------+
| 2017-04-02 | 19.12741903076923 | 44.614721153846155 | 32.1250 | Alcatel |
| 2017-04-02 | 0 | 0 | 0 | Vodafone |
| 2017-03-31 | 18.30683616557377 | 44.294387978142076 | 34.7432 | Alcatel |
| 2017-03-31 | 20.643555595555555 | 50.99801587301587 | 32.1640 | Vodafone |
这背后的逻辑基本上是为当天未进行速度测试的电信添加一个空行。进一步说明:我需要这样做的原因是因为 MySQL 数据库中的 table 没有为未完成的测试记录 row/entry,因此我的原始结果集中缺少一行,因此我需要添加 'NULL/0' 行以反映那天该电信公司缺乏测试。我目前无法直接访问该数据库来修改条目,所以这是我能想到的最好的方法。
知道我该怎么做吗?感谢您的帮助!
您可以使用mysql的NULLIF()
功能。在函数中,您提供用于测试速度测试是否完成的变量。假设当天没有进行速度测试时,延迟将为零。
然后 NULLIF(latency,0)
将是插入命令中列延迟的值。因此,对于其他列,您需要在某些条件下填写 NULL。此函数 returns NULL 如果 第一个参数 与 第二个参数 匹配。否则给出第一个参数的实际值。
听起来您想在事后向 ResultSet 添加行。 AFAIK,我们不能那样做。相反,我们需要构造我们的 SQL 查询,以便它将生成我们需要的 "extra" 行。
所以如果我们有一个名为 "test" 和
的 table
SELECT * FROM test
ORDER BY test_date DESC, network_operator_name
产生
test_date upload_kbps download_kbps latency network_operator_name
---------- ---------------- ---------------- ------- ---------------------
2017-04-02 19.1274190307692 44.6147211538461 32.125 Alcatel
2017-03-31 18.3068361655737 44.294387978142 34.7432 Alcatel
2017-03-31 20.6435555955555 50.9980158730158 32.164 Vodafone
然后我们可以从查询开始,为 test_date
和 network_operator_name
的每个组合生成一行
SELECT test_date, network_operator_name
FROM
(SELECT DISTINCT network_operator_name FROM test) unique_operators
CROSS JOIN
(SELECT DISTINCT test_date FROM test) unique_dates
这给了我们
test_date network_operator_name
---------- ---------------------
2017-03-31 Alcatel
2017-03-31 Vodafone
2017-04-02 Alcatel
2017-04-02 Vodafone
然后我们可以 LEFT JOIN 该查询与实际的 table
SELECT
required_rows.test_date,
COALESCE(test.upload_kbps, 0) AS upload_kbps,
COALESCE(test.download_kbps, 0) AS download_kbps,
COALESCE(test.latency, 0) AS latency,
required_rows.network_operator_name
FROM
(
SELECT test_date, network_operator_name
FROM
(SELECT DISTINCT network_operator_name FROM test) unique_operators
CROSS JOIN
(SELECT DISTINCT test_date FROM test) unique_dates
) required_rows
LEFT JOIN
test
ON required_rows.test_date = test.test_date
AND required_rows.network_operator_name = test.network_operator_name
ORDER BY required_rows.test_date DESC, required_rows.network_operator_name
生产
test_date upload_kbps download_kbps latency network_operator_name
---------- ---------------- ---------------- ------- ---------------------
2017-04-02 19.1274190307692 44.6147211538461 32.125 Alcatel
2017-04-02 0 0 0 Vodafone
2017-03-31 18.3068361655737 44.294387978142 34.7432 Alcatel
2017-03-31 20.6435555955555 50.9980158730158 32.164 Vodafone
我有一个结果集 table 如下所示:
+------------+--------------------+--------------------+---------+-----------------------+
| test_date | upload_kbps | download_kbps | latency | network_operator_name |
+------------+--------------------+--------------------+---------+-----------------------+
| 2017-04-02 | 19.12741903076923 | 44.614721153846155 | 32.1250 | Alcatel |
| 2017-03-31 | 18.30683616557377 | 44.294387978142076 | 34.7432 | Alcatel |
| 2017-03-31 | 20.643555595555555 | 50.99801587301587 | 32.1640 | Vodafone |
我想修改 ResultSet 以供进一步使用,同时我将一行添加到 ResultSet 中,如下所示:
+------------+--------------------+--------------------+---------+-----------------------+
| test_date | upload_kbps | download_kbps | latency | network_operator_name |
+------------+--------------------+--------------------+---------+-----------------------+
| 2017-04-02 | 19.12741903076923 | 44.614721153846155 | 32.1250 | Alcatel |
| 2017-04-02 | 0 | 0 | 0 | Vodafone |
| 2017-03-31 | 18.30683616557377 | 44.294387978142076 | 34.7432 | Alcatel |
| 2017-03-31 | 20.643555595555555 | 50.99801587301587 | 32.1640 | Vodafone |
这背后的逻辑基本上是为当天未进行速度测试的电信添加一个空行。进一步说明:我需要这样做的原因是因为 MySQL 数据库中的 table 没有为未完成的测试记录 row/entry,因此我的原始结果集中缺少一行,因此我需要添加 'NULL/0' 行以反映那天该电信公司缺乏测试。我目前无法直接访问该数据库来修改条目,所以这是我能想到的最好的方法。
知道我该怎么做吗?感谢您的帮助!
您可以使用mysql的NULLIF()
功能。在函数中,您提供用于测试速度测试是否完成的变量。假设当天没有进行速度测试时,延迟将为零。
然后 NULLIF(latency,0)
将是插入命令中列延迟的值。因此,对于其他列,您需要在某些条件下填写 NULL。此函数 returns NULL 如果 第一个参数 与 第二个参数 匹配。否则给出第一个参数的实际值。
听起来您想在事后向 ResultSet 添加行。 AFAIK,我们不能那样做。相反,我们需要构造我们的 SQL 查询,以便它将生成我们需要的 "extra" 行。
所以如果我们有一个名为 "test" 和
的 tableSELECT * FROM test
ORDER BY test_date DESC, network_operator_name
产生
test_date upload_kbps download_kbps latency network_operator_name
---------- ---------------- ---------------- ------- ---------------------
2017-04-02 19.1274190307692 44.6147211538461 32.125 Alcatel
2017-03-31 18.3068361655737 44.294387978142 34.7432 Alcatel
2017-03-31 20.6435555955555 50.9980158730158 32.164 Vodafone
然后我们可以从查询开始,为 test_date
和 network_operator_name
SELECT test_date, network_operator_name
FROM
(SELECT DISTINCT network_operator_name FROM test) unique_operators
CROSS JOIN
(SELECT DISTINCT test_date FROM test) unique_dates
这给了我们
test_date network_operator_name
---------- ---------------------
2017-03-31 Alcatel
2017-03-31 Vodafone
2017-04-02 Alcatel
2017-04-02 Vodafone
然后我们可以 LEFT JOIN 该查询与实际的 table
SELECT
required_rows.test_date,
COALESCE(test.upload_kbps, 0) AS upload_kbps,
COALESCE(test.download_kbps, 0) AS download_kbps,
COALESCE(test.latency, 0) AS latency,
required_rows.network_operator_name
FROM
(
SELECT test_date, network_operator_name
FROM
(SELECT DISTINCT network_operator_name FROM test) unique_operators
CROSS JOIN
(SELECT DISTINCT test_date FROM test) unique_dates
) required_rows
LEFT JOIN
test
ON required_rows.test_date = test.test_date
AND required_rows.network_operator_name = test.network_operator_name
ORDER BY required_rows.test_date DESC, required_rows.network_operator_name
生产
test_date upload_kbps download_kbps latency network_operator_name
---------- ---------------- ---------------- ------- ---------------------
2017-04-02 19.1274190307692 44.6147211538461 32.125 Alcatel
2017-04-02 0 0 0 Vodafone
2017-03-31 18.3068361655737 44.294387978142 34.7432 Alcatel
2017-03-31 20.6435555955555 50.9980158730158 32.164 Vodafone