所以我有一个奇怪的例子,两个非常相似的查询返回不同的结果。第一个查询是:
select src.period_num period_num,
src.flag flag,
src.week_num week_num,
((src.year_num * 100) + src.period_num) year_num,
count(distinct src.id) result_count
from src_table src
group by src.period_num,
src.flag,
src.week_num,
((src.year_num * 100) + src.period_num)
第二个查询是:
select src.period_num period_num,
src.flag flag,
src.week_num week_num,
((src.year_num * 100) | src.period_num) year_num,
count(distinct src.id) result_count
from src_table src
group by src.period_num,
src.flag,
src.week_num,
((src.year_num * 100) | src.period_num)
正如您所看到的,查询只有一个不同之处—第一个查询使用加法(+),第二个查询使用按位or(|),我的问题是,对于第一个查询,我们接收类似这样的结果(我只留下了重要部分):
+-------------+---------+-----------+-----------+---------------+--+
| period_num | flag | week_num | year_num | result_count |
+-------------+---------+-----------+-----------+---------------+--+
| 6 | true | 21 | 201906 | 94 |
第二个返回:
+-------------+---------+-----------+-----------+---------------+--+
| period_num | flag | week_num | year_num | result_count |
+-------------+---------+-----------+-----------+---------------+--+
| 6 | true | 21 | 201902 | 87 |
| 6 | false | 21 | 201902 | 7 |
第二个结果计数是正确的,具有正确的分组标志,但是您可以看到,现在year\u num搞砸了。不管怎么说,我的主要问题是,我无法理解第一个查询到底出了什么问题,因为它似乎没有什么根本不好的地方。任何想法和帮助都将不胜感激。
1条答案
按热度按时间nc1teljy1#
按位“或”是与加法完全不同的操作。因此,它将产生完全不同的结果。
考虑下面两个二进制“操作”的例子。
第一次加法(1+3=4):
和位或(1 | 3=3):
我希望这对你的问题有帮助。
哦,记住,将一个数字乘以100将引入以10为底的两个尾随零(十进制),但在二进制中,仍然可以将位设置为最低有效位。
例如,201900是
110001010010101100
二进制的。如果没有更多的细节,很难解释为什么src.flag仅仅通过使用按位or而不是加法就可以神奇地从false变为true。有没有可能在准备你的例子时,你不小心改变了其他的东西?
正如我所承诺的,我已经通过sparksql运行了您的示例数据。我将您的数据集缩减为仅包含年份为2019、期间为6的94条记录。
下面是运行的结果,显示了为两个查询生成的相同答案。接下来是整个序列,你可以尝试自己,如果你有权访问Spark壳。有可能 hive 里有虫子,但我不会从这个假设开始。
以下是全部工作:
你能在spark shell里试试这个吗?