Impala last_value 在视图中返回不一致的结果
Impala last_value Returning Inconsistent Result in View
我有一些按以下方式格式化的数据,但在创建具有正确输出的 Impala 视图时遇到问题。
让我们称之为 table h_test_daily:
+--------+-----------+-------+
| Tag_ID | Date | Value |
+--------+-----------+-------+
| 1 | 7/10/2017 | 10 |
| 1 | 7/10/2017 | |
| 1 | 7/9/2017 | 8 |
| 2 | 7/10/2017 | 20 |
| 2 | 7/10/2017 | 16 |
| 2 | 7/9/2017 | 9 |
| 3 | 7/10/2017 | |
| 3 | 7/10/2017 | 10 |
| 3 | 7/9/2017 | 5 |
| 4 | 7/10/2017 | 13 |
| 4 | 7/10/2017 | |
| 4 | 7/9/2017 | 18 |
+--------+-----------+-------+
我正在尝试使用 Impala(在 HUE 服务器上)对其执行 last_value() 聚合。现在执行以下 SQL 工作正常:
SELECT DISTINCT Tag_ID, `Date`, Value FROM
(SELECT Tag_ID,
`Date`,
last_value(Value IGNORE NULLS) over (PARTITION BY Tag_ID, `Date`
ORDER BY `Date` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as Value
FROM test.h_test_daily)
TAB
;
这个输出是正确的。我得到每个标签的最后一个值,每个日期。
+--------+-----------+----------+
| Tag_ID | Date | Value |
+--------+-----------+----------+
| 3 | 7/10/2017 | 10 |
| 4 | 7/10/2017 | 13 |
| 1 | 7/10/2017 | 10 |
| 1 | 7/9/2017 | 8 |
| 4 | 7/9/2017 | 18 |
| 2 | 7/9/2017 | 9 |
| 3 | 7/9/2017 | 5 |
| 2 | 7/10/2017 | 16 |
+--------+-----------+----------+
因此,当我尝试使用 SQL 创建视图时,它做了一些奇怪的事情。我开始看到空值。它在哪里获取最后一个值,现在查看它是否为空。 table 不会发生此问题。我希望我做错了什么,创建视图只会显示它。
这是视图的输出:
+--------+-----------+----------+
| Tag_ID | Date | Value |
+--------+-----------+----------+
| 3 | 7/10/2017 | 10 |
| 1 | 7/9/2017 | 8 |
| 4 | 7/9/2017 | 18 |
| 4 | 7/10/2017 | NULL |
| 1 | 7/10/2017 | NULL |
| 2 | 7/9/2017 | 9 |
| 3 | 7/9/2017 | 5 |
| 2 | 7/10/2017 | 16 |
+--------+-----------+----------+
编辑:
我做了一大堆改变,但我仍然遇到同样的问题。这是我尝试过的:
添加了名为 mins
的列
正如戈登指出的那样,我的顺序是错误的。每个分区都有相同的排序键。 table 是来自几个传感器的数据,每小时更新一整小时的数据。所以我为每一行添加了一个 mins 列。 (这与 Tag_ID 组合时是唯一的)
这是更新后的 table 和 SQL
+--------+-----------+-------+------+
| Tag_ID | Date | Value | mins |
+--------+-----------+-------+------+
| 1 | 7/9/2017 | 8 | 10 |
| 1 | 7/10/2017 | 10 | 10 |
| 1 | 7/10/2017 | 13 | 11 |
| 1 | 7/10/2017 | | 12 |
| 2 | 7/9/2017 | 9 | 10 |
| 2 | 7/10/2017 | 15 | 10 |
| 2 | 7/10/2017 | 16 | 11 |
| 3 | 7/9/2017 | 5 | 10 |
| 3 | 7/10/2017 | | 10 |
| 3 | 7/10/2017 | 10 | 11 |
| 4 | 7/9/2017 | 18 | 10 |
| 4 | 7/10/2017 | 13 | 10 |
| 4 | 7/10/2017 | | 11 |
+--------+-----------+-------+------+
现在对于 select 语句和创建视图我 运行 进入相同的问题。这是更新后的 SQL 声明:
SELECT DISTINCT Tag_ID, `Date`, Value FROM
(SELECT Tag_ID,
`Date`,
last_value(Value ignore nulls) over (PARTITION BY Tag_ID, `Date` ORDER BY
mins ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as Value
FROM test.h_test_daily)
TAB
;
然后我试图过滤掉子select中的null
值,所以我添加了一个WHERE Value IS NOT NULL
。这样做的问题是,在实际数据集中,大约有 40 个不同的 Value 列提供不同的信息。因此即使其他值之一是 not null
,该列也会从查询中删除。
最终编辑: 我联系了 Cloudera 的支持团队来澄清这个问题。他们回来说这是一个 Impala 问题。因为他们没有考虑创建视图中的 ignore nulls
参数。此问题计划在 2.10.0 中修复。这是错误线程:Link
这既不是视图也不是 table 的问题。问题出在您的查询上。您有 order by date
,但您也按日期进行分区。因此,分区的日期是常量。
在 SQL 中排序 unstable。这意味着当键相同时,它们可以以任何顺序出现——而且确实如此。为什么?原因很简单:SQL tables代表无序集合。没有默认排序顺序。
事实是,查询在这两种情况下都不起作用。它恰好看起来在一种情况下有效,但在另一种情况下无效。您需要另一个键来进行排序 stable,因此将始终选择相同的先前值。
我有一些按以下方式格式化的数据,但在创建具有正确输出的 Impala 视图时遇到问题。 让我们称之为 table h_test_daily:
+--------+-----------+-------+
| Tag_ID | Date | Value |
+--------+-----------+-------+
| 1 | 7/10/2017 | 10 |
| 1 | 7/10/2017 | |
| 1 | 7/9/2017 | 8 |
| 2 | 7/10/2017 | 20 |
| 2 | 7/10/2017 | 16 |
| 2 | 7/9/2017 | 9 |
| 3 | 7/10/2017 | |
| 3 | 7/10/2017 | 10 |
| 3 | 7/9/2017 | 5 |
| 4 | 7/10/2017 | 13 |
| 4 | 7/10/2017 | |
| 4 | 7/9/2017 | 18 |
+--------+-----------+-------+
我正在尝试使用 Impala(在 HUE 服务器上)对其执行 last_value() 聚合。现在执行以下 SQL 工作正常:
SELECT DISTINCT Tag_ID, `Date`, Value FROM
(SELECT Tag_ID,
`Date`,
last_value(Value IGNORE NULLS) over (PARTITION BY Tag_ID, `Date`
ORDER BY `Date` ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as Value
FROM test.h_test_daily)
TAB
;
这个输出是正确的。我得到每个标签的最后一个值,每个日期。
+--------+-----------+----------+
| Tag_ID | Date | Value |
+--------+-----------+----------+
| 3 | 7/10/2017 | 10 |
| 4 | 7/10/2017 | 13 |
| 1 | 7/10/2017 | 10 |
| 1 | 7/9/2017 | 8 |
| 4 | 7/9/2017 | 18 |
| 2 | 7/9/2017 | 9 |
| 3 | 7/9/2017 | 5 |
| 2 | 7/10/2017 | 16 |
+--------+-----------+----------+
因此,当我尝试使用 SQL 创建视图时,它做了一些奇怪的事情。我开始看到空值。它在哪里获取最后一个值,现在查看它是否为空。 table 不会发生此问题。我希望我做错了什么,创建视图只会显示它。
这是视图的输出:
+--------+-----------+----------+
| Tag_ID | Date | Value |
+--------+-----------+----------+
| 3 | 7/10/2017 | 10 |
| 1 | 7/9/2017 | 8 |
| 4 | 7/9/2017 | 18 |
| 4 | 7/10/2017 | NULL |
| 1 | 7/10/2017 | NULL |
| 2 | 7/9/2017 | 9 |
| 3 | 7/9/2017 | 5 |
| 2 | 7/10/2017 | 16 |
+--------+-----------+----------+
编辑: 我做了一大堆改变,但我仍然遇到同样的问题。这是我尝试过的:
添加了名为 mins
的列正如戈登指出的那样,我的顺序是错误的。每个分区都有相同的排序键。 table 是来自几个传感器的数据,每小时更新一整小时的数据。所以我为每一行添加了一个 mins 列。 (这与 Tag_ID 组合时是唯一的)
这是更新后的 table 和 SQL
+--------+-----------+-------+------+
| Tag_ID | Date | Value | mins |
+--------+-----------+-------+------+
| 1 | 7/9/2017 | 8 | 10 |
| 1 | 7/10/2017 | 10 | 10 |
| 1 | 7/10/2017 | 13 | 11 |
| 1 | 7/10/2017 | | 12 |
| 2 | 7/9/2017 | 9 | 10 |
| 2 | 7/10/2017 | 15 | 10 |
| 2 | 7/10/2017 | 16 | 11 |
| 3 | 7/9/2017 | 5 | 10 |
| 3 | 7/10/2017 | | 10 |
| 3 | 7/10/2017 | 10 | 11 |
| 4 | 7/9/2017 | 18 | 10 |
| 4 | 7/10/2017 | 13 | 10 |
| 4 | 7/10/2017 | | 11 |
+--------+-----------+-------+------+
现在对于 select 语句和创建视图我 运行 进入相同的问题。这是更新后的 SQL 声明:
SELECT DISTINCT Tag_ID, `Date`, Value FROM
(SELECT Tag_ID,
`Date`,
last_value(Value ignore nulls) over (PARTITION BY Tag_ID, `Date` ORDER BY
mins ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as Value
FROM test.h_test_daily)
TAB
;
然后我试图过滤掉子select中的null
值,所以我添加了一个WHERE Value IS NOT NULL
。这样做的问题是,在实际数据集中,大约有 40 个不同的 Value 列提供不同的信息。因此即使其他值之一是 not null
,该列也会从查询中删除。
最终编辑: 我联系了 Cloudera 的支持团队来澄清这个问题。他们回来说这是一个 Impala 问题。因为他们没有考虑创建视图中的 ignore nulls
参数。此问题计划在 2.10.0 中修复。这是错误线程:Link
这既不是视图也不是 table 的问题。问题出在您的查询上。您有 order by date
,但您也按日期进行分区。因此,分区的日期是常量。
在 SQL 中排序 unstable。这意味着当键相同时,它们可以以任何顺序出现——而且确实如此。为什么?原因很简单:SQL tables代表无序集合。没有默认排序顺序。
事实是,查询在这两种情况下都不起作用。它恰好看起来在一种情况下有效,但在另一种情况下无效。您需要另一个键来进行排序 stable,因此将始终选择相同的先前值。