Hive Cli / HiveServer2 中使用 dayofweek 函数引发的BUG!

文章目录

      • 前言
      • dayofweek 函数官方说明
      • BUG 重现
      • Spark SQL 中的使用
      • 总结

前言

使用的集群环境为:

  • hive 3.1.2
  • spark 3.0.2

dayofweek 函数官方说明

dayofweek(date) - Returns the day of the week for date/timestamp (1 = Sunday, 2 = Monday, …, 7 = Saturday).

根据所给日期,返回该日期对应的周几数字,如:

周日 —— 1
周一 —— 2
周二 —— 3

周六 —— 7

BUG 重现

当前我有一张订单详情信息测试表,如下所示:

在这里插入图片描述
需求:获取某一个区间内周一至周日每天各个商品的售卖量,Hive SQL 代码如下:

selectsku_id,sum(if(`dayofweek`(create_date)=2,sku_num,0)) Monday,sum(if(`dayofweek`(create_date)=3,sku_num,0)) Tuesday,sum(if(`dayofweek`(create_date)=4,sku_num,0)) Wednesday,sum(if(`dayofweek`(create_date)=5,sku_num,0)) Thursday,sum(if(`dayofweek`(create_date)=6,sku_num,0)) Friday,sum(if(`dayofweek`(create_date)=7,sku_num,0)) Saturday,sum(if(`dayofweek`(create_date)=1,sku_num,0)) Sunday
fromorder_detail
wherecreate_date >= "2021-09-27"andcreate_date <= "2021-10-03"
group bysku_id;

该代码运行后,部分结果如下所示:

在这里插入图片描述
在我验证结果的时候,第一行就出现了错误,查看订单详情信息测试表发现,sku_id1 的商品在 2021-09-27(周一)这天售出了 2 件商品;

而在我们上面的代码运行结果中,发现 monday 周一统计的出售商品数量为 0,但是我们的 SQL 代码逻辑并没有出现问题啊。

在这里插入图片描述

反而像是该函数执行的结果,将整体向后平移了一个维度,saturday 的值是 sunday 的值,sunday 的值是 monday 的值…

那么为什么会出现这个问题呢?我就想到了可能是数据类型的问题,上面表结构中提到了,create_date 这个字段的类型是 string,而 dayofweek() 函数的参数是一个 date 类型的数据。

于是,我对数据类型进行了转换,然后便有了下面的结果:

selectsku_id,sum(if(`dayofweek`(cast(create_date as date))=2,sku_num,0)) Monday,sum(if(`dayofweek`(cast(create_date  as date))=3,sku_num,0)) Tuesday,sum(if(`dayofweek`(cast(create_date  as date))=4,sku_num,0)) Wednesday,sum(if(`dayofweek`(cast(create_date  as date))=5,sku_num,0)) Thursday,sum(if(`dayofweek`(cast(create_date  as date))=6,sku_num,0)) Friday,sum(if(`dayofweek`(cast(create_date  as date))=7,sku_num,0)) Saturday,sum(if(`dayofweek`(cast(create_date  as date))=1,sku_num,0)) Sunday
fromorder_detail
wherecreate_date >= "2021-09-27"andcreate_date <= "2021-10-03"
group bysku_id;

这次得到的结果就是正确的了。

在这里插入图片描述

但是令我不解的又来了,在我的印象中 dayofweek() 函数是可以直接传递一个 string 类型的数据啊。

如下所示:

在这里插入图片描述
2021-09-27 是周一,所以返回的结果是 2,显然这是正确的,那么为什么同样是 string 类型,这里是正常的,上面的代码中发生了异常。

然后我就想到,会不是是因为多个函数嵌套引发的 BUG,因为我们在最初的 SQL 中是这样写的:

    sum(if(`dayofweek`(create_date)=2,sku_num,0)) Monday,sum(if(`dayofweek`(create_date)=3,sku_num,0)) Tuesday,sum(if(`dayofweek`(create_date)=4,sku_num,0)) Wednesday,sum(if(`dayofweek`(create_date)=5,sku_num,0)) Thursday,sum(if(`dayofweek`(create_date)=6,sku_num,0)) Friday,sum(if(`dayofweek`(create_date)=7,sku_num,0)) Saturday,sum(if(`dayofweek`(create_date)=1,sku_num,0)) Sunday

嵌套了 sumif 以及 dayofweek 函数,于是,我不执行 sum 操作,并且不进行数据类型转换,看看周几判断结果是否正确,如下所示:

selectsku_id,if(`dayofweek`(create_date)=2,sku_num,0) Monday,if(`dayofweek`(create_date)=3,sku_num,0) Tuesday,if(`dayofweek`(create_date)=4,sku_num,0) Wednesday,if(`dayofweek`(create_date)=5,sku_num,0) Thursday,if(`dayofweek`(create_date)=6,sku_num,0) Friday,if(`dayofweek`(create_date)=7,sku_num,0) Saturday,if(`dayofweek`(create_date)=1,sku_num,0) Sunday
fromorder_detail
wherecreate_date >= "2021-09-27"andcreate_date <= "2021-10-03"

在这里插入图片描述

可以发现周几判断结果是对的。

但只要我加上 sum 聚合操作之后,就会发生异常,这种错误呢又可以通过转换数据类型进行规避,属于是闭环了家人们。

Spark SQL 中的使用

当我使用 Spark SQL 完成上面【BUG重现】中的需求时,发现【BUG重现】中最开始的 SQL 代码在这里是正常运行的,即使没有进行数据类型转换、而且使用了聚合函数的嵌套。

        spark.sql("""|select|    sku_id,|    sum(if(`dayofweek`(create_date)=2,sku_num,0)) Monday,|    sum(if(`dayofweek`(create_date)=3,sku_num,0)) Tuesday,|    sum(if(`dayofweek`(create_date)=4,sku_num,0)) Wednesday,|    sum(if(`dayofweek`(create_date)=5,sku_num,0)) Thursday,|    sum(if(`dayofweek`(create_date)=6,sku_num,0)) Friday,|    sum(if(`dayofweek`(create_date)=7,sku_num,0)) Saturday,|    sum(if(`dayofweek`(create_date)=1,sku_num,0)) Sunday|from|    order_detail|where|    create_date >= "2021-09-27"|    and|    create_date <= "2021-10-03"|group by|    sku_id|order by|    sku_id;|""".stripMargin).show()

在这里插入图片描述

最终的结果是正确的。

可以看出 Spark SQL 对其进行了优化,正经人平常谁用【Hive Cli / HiveServer2】啊!一天天整这破事。

我不是正经人…

总结

当我们的使用场景为【Hive Cli / HiveServer2】时:

在嵌套使用 dayofweek 函数的时候,将传递的参数转换为 date 类型,不要用 string 类型,从而避免引发该 BUG。

当我们的使用场景为【Spark SQL】时:

并不会出现该BUG。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/48423.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据封装与解封装过程

2.2数据封装与解封装过程(二) 如果网络世界只有终端设备&#xff0c;那么将不能称之为网络。正因为有很多中转设备才形成了今天如此复杂的Internet网络&#xff0c;只不过一贯作为网络用户的我们没有机会感知它们的存在&#xff0c;这都是传输层的“功劳”&#xff0c;由于传输…

在外SSH远程连接macOS服务器

文章目录 前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS 4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址 5. 使用固定TCP端口地址ssh远程 …

科技云报道:云计算下半场,公有云市场生变,私有云风景独好

科技云报道原创。 大数据、云计算、人工智能&#xff0c;组成了恢弘的万亿级科技市场。这三个领域&#xff0c;无论远观近观&#xff0c;都如此性感和魅力&#xff0c;让一代又一代创业者为之杀伐攻略。 然而高手过招往往一瞬之间便已胜负知晓&#xff0c;云计算市场的巨幕甫…

测试框架pytest教程(11)-pytestAPI

常量 pytest.__version__ #输出pytest版本 pytest.version_tuple #输出版本的元组形式 功能 pytest.approx pytest.approx 是一个用于进行数值近似比较的 pytest 断言工具。 在测试中&#xff0c;有时候需要对浮点数或其他具有小数部分的数值进行比较。然而&#xff0c;由于…

Node.JS教程

文章目录 Node.JSNode.js学习指南一、Node.js基础1.认识Node.js2.开发环境搭建3. 模块、包、commonJS3.1、为什么要有模块化开发&#xff1f;3.2、CommonJS规范3.3、 modules模块化规范写法 总结 Node.JS Node.js学习指南 服务端开发底层平台周边生态 学习前提 JavaScript、E…

Rspack 创建 vue2/3 项目接入 antdv(rspack.config.js 配置 less 主题)

一、简介 Rspack CLI 官方文档。 rspack.config.js 官方文档。 二、创建 vue 项目 创建项目&#xff08;文档中还提供了 Rspack 内置 monorepo 框架 Nx 的创建方式&#xff0c;根据需求进行选择&#xff09; # npm 方式 $ npm create rspacklatest# yarn 方式 $ yarn create…

html动态爱心代码【二】(附源码)

目录 前言 效果演示 内容修改 完整代码 总结 前言 七夕马上就要到了&#xff0c;为了帮助大家高效表白&#xff0c;下面再给大家带来了实用的HTML浪漫表白代码(附源码)背景音乐&#xff0c;可用于520&#xff0c;情人节&#xff0c;生日&#xff0c;表白等场景&#xff0c…

【Python】【数据结构和算法】查找最大或最小的N个元素

除了直接排序&#xff0c;还可以利用heaq模块的nlargest()和nsmallest()方法&#xff0c;例如&#xff1a; >>> nums [3, 5, 2, 4, 1] >>> smallest heapq.nsmallest(3, nums) >>> print(smallest) [1, 2, 3] >>> largest heapq.nlarg…

【C#基础】unity中结构体的使用

【C#基础】unity中结构体的使用 结构体&#xff08;Struct&#xff09;是值类型数据结构&#xff0c;在栈上分配内存&#xff0c;可以包含字段&#xff0c;属性&#xff0c;方法&#xff0c;构造函数。结构体可以实现接口&#xff0c;但是不能继承。在Dots里有大量依靠Struct实…

Android 面试之Glide做了哪些优化?

前言 Glide可以说是最常用的图片加载框架了&#xff0c;Glide链式调用使用方便&#xff0c;性能上也可以满足大多数场景的使用&#xff0c;Glide源码与原理也是面试中的常客。 但是Glide的源码内容比较多&#xff0c;想要学习它的源码往往千头万绪&#xff0c;一时抓不住重点.…

搭建自己的私有 开源LoRaWAN 网络服务器(The ThingsStack)---之配置

介绍 这是使用 Docker 在您自己的硬件上安装 Things Stack Enterprise 或开源代码以运行您自己的私有 LoRaWAN 网络服务器的指南。 运行 The Things Stack 的方法有多种。 Things Stack 开源和企业发行版旨在在您自己的硬件上运行,本指南也对此进行了介绍。 对于具有高吞吐量的…

shell脚本免交互

一.Here Document免交互 1.免交互概述 使用I/O重定向的方式将命令列表提供给交互式程序 是一种标准输入&#xff0c;只能接收正确的指令或命令 2.格式&#xff1a; 命令 <<标记 ....... 内容 #标记之间是传入内容 ....... 标记 注意事项 标记可以使用任意的合法…

Cesium 相机的三种放置方式

文章目录 Cesium 相机的三种放置方式第一种&#xff1a;setView 计算视角1. Cartesian3 方式2. Rectangle 方式 第二种&#xff1a;flyTo第三种&#xff1a;lookAt Cesium 相机的三种放置方式 Cesium 提供了三种方式对相机的位置进行摆放 第一种&#xff1a;setView 计算视角 …

mybatisplus批量写入

1.新建MybatisPlusConfig /*** MybatisPlusConfig.*/ Configuration MapperScan("com.test.mapper") public class MybatisPlusConfig {/*** 自定义批量插入 SQL 注入器.*/Beanpublic InsertBatchSqlInjector insertBatchSqlInjector() {return new InsertBatchSqlI…

android 申请电池优化,自启动,无障碍权限

代码仅用于自己记忆,都是实际跑过的 /*** 引导开通-无障碍服务 可以跳转到系统的无障碍功能,并高亮自己的app*/fun gotoAccessibilitySetting(context: Context) {val EXTRA_FRAGMENT_ARG_KEY ":settings:fragment_args_key";val EXTRA_SHOW_FRAGMENT_ARGUMENTS &q…

WPF 项目中 MVVM模式 的简单例子说明

一、概述 MVVM 是 Model view viewModel 的简写。MVVM模式有助于将应用程序的业务和表示逻辑与用户界面清晰分离。 几个概念的说明&#xff1a; model :数据&#xff0c;界面中需要的数据&#xff0c;最好不要加逻辑代码view : 视图就是用户看到的UI结构 xaml 文件viewModel …

Docker 的基本概念和优势,以及在应用程序开发中的实际应用

Docker 是一款开源的容器化平台&#xff0c;它可以将应用程序及其依赖项打包成一个运行环境&#xff0c;使得应用程序可以在任何地方运行&#xff0c;而不需要考虑底层系统的差异性。下面是 Docker 的基本概念和优势&#xff1a; 基本概念&#xff1a; Docker 镜像&#xff1…

一文了解汽车芯片的分类及用途介绍

汽车芯片按其功能可分为控制类&#xff08;MCU和AI芯片&#xff09;、功率类、传感器和其他&#xff08;如存储器&#xff09;四种类型。市场基本被国际巨头所垄断。人们常说的汽车芯片是指汽车里的计算芯片&#xff0c;按集成规模可分为MCU芯片和AI芯片&#xff08;SoC芯片&am…

JavaScript模块化历程(一)

文章目录 1. 模块化概述2. 模块化演变[^2]2.1.文件划分模式(了解)2.2.命名空间模式(了解)2.3.IIFE(立即执行函数表达式)和参数依赖声明(了解) 3.模块化规范3.1 CommonJSRequire的基本实现逻辑(重点看) 3.2 AMDAMD的基本实现逻辑(重点看) 3.3 CMD 4.模块化标准规范 1. 模块化概述…

Lua之Lua源文件批量转换为luac字节码文件

准备的工具&#xff1a;luac.exe CSDNhttps://mp.csdn.net/mp_download/manage/download/UpDetailed Unity版: using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine;public static class Bat…