当前位置: 首页 > news >正文

网站建设违约/百度广告平台电话

网站建设违约,百度广告平台电话,网站建设 排行,寮步网站建设目录 0 前言 1 需求案例 2 问题分析 0 前言 我们都知道oracle,mysql或greenplum中都支持不等连接,但在hive数据库中2.1之前的版本是不支持的,那么对一些需要不等连接的语句就需要改写,或寻找其他实现方案,那么有没有一种替代的…

目录

0 前言

1 需求案例

2 问题分析


0 前言

我们都知道oracle,mysql或greenplum中都支持不等连接,但在hive数据库中2.1之前的版本是不支持的,那么对一些需要不等连接的语句就需要改写,或寻找其他实现方案,那么有没有一种替代的解决方案呢?本文就针对这一问题进行探讨。

1 需求案例

如下两张表

t表

iddt
12022-06-03
22022-05-04
32022-04-01
42022-05-22

t1表

iddt
12022-04-01
22022-05-30
32022-04-03

两张表根据id进行关联其中t表为主表,并获取t表中dt大于t1表的中的dt的数据。

数据准备

创建t表

create table t as
select 1 as id,'2022-06-03' as dt
union all 
select 2 as id,'2022-05-04' as dt
union all 
select 3 as id,'2022-04-01' as dt
union all
select 4 as id,'2022-05-22' as dt
t.id    t.dt
1       2022-06-03
2       2022-05-04
3       2022-04-01
4       2022-05-22

创建t1表

create table t1 as
select 1 as id,'2022-04-01' as dt
union all
select 2 as id,'2022-05-30' as dt
union all
select 3 as id,'2022-04-03' as dt
t1.id   t1.dt
1       2022-04-01
2       2022-05-30
3       2022-04-03

 

2 问题分析

情形1:非等值连接区间连接

针对 上述问题如果在mysql中我们做法如下:

select t.id, t.dt, t1.dt
from t lfetjoin t1 on t1.id = t1.idand t.dt > t1.dt

但是在hive2.2之前的版本中会报语法错误,针对此问题的替代方案,查阅了一些资料,给出的解决方案如下:一种是采用locate()匹配的方式

或是采用自关联在where中进行过滤

其实这两种方式本质上一样的,都是进行笛卡尔集然后where中过滤,这种对于join类型的关联没什么问题,但对于left join或right join就有问题了,因为数据的记录数会丢失。为了保证记录数不丢失,本文采用嵌套关联的方式,也就是原来的主表不变,把需要不等条件的这种放在where条件中过滤单独求出结果集,外层再根据关联条件和主表再做left join具体SQL如下:

第一步:求出满足条件的结果集

select t.id, t.dt,t1.dt
from tleft join t1 on t.id = t1.id
where t.dt > coalesce(t1.dt,0)
order by id

结果如下:

t.id    t.dt    t1.dt
1       2022-06-03      2022-04-01
4       2022-05-22      NULL

第二步:用主表t left join 第一步的结果集

select *
from tleft join(select t.id as id, t1.dt as dtfrom tleft  join t1 on t.id = t1.idwhere t.dt > coalesce(t1.dt, 0)) t2on t.id = t2.id

结果如下:

OK
t.id    t.dt    t2.id   t2.dt
2       2022-05-04      NULL    NULL
3       2022-04-01      NULL    NULL
1       2022-06-03      1       2022-04-01
4       2022-05-22      4       NULL
Time taken: 3.392 seconds, Fetched: 4 row(s)

如果直接采用自关联形式获取结果,代码如下:

select t.id, t.dt,t1.dt
from t,t1
where t.id=t1.idand  t.dt > coalesce(t1.dt,0)
order by id

最终结果如下:

t.id    t.dt    t1.dt
1       2022-06-03      2022-04-01
Time taken: 2.291 seconds, Fetched: 1 row(s)

可以看出最终的结果集变小,不是想要的结果。

对于关联健如本题的id,本身关联的时候不能唯一确定一条数据,也就是关联的时候数据产生了膨胀,这类求解的时候注意上层去重。

情形2:非等值连接or连接

对于本题外,如果非等值连接中出现or连接的这种情况,可以采用union的形式进行改写。例如如下数据

t表

iddt
12022-06-03
22022-05-04
32022-04-01
42022-05-22

t1表:

iddt1dt2
12022-06-03                                                               2022-05-03
22022-05-25                                                               2022-05-04
32022-03-01                                                               2022-05-04

找出t表中时间字段dt在t1表中dt1,dt2任意出现的id,及时间,保留t表中数据,如果能够匹配到取匹配的时间,未匹配到置为NULL

数据准备:

create table t as
select 1 as id,'2022-06-03' as dt
union all 
select 2 as id,'2022-05-04' as dt
union all 
select 3 as id,'2022-04-01' as dt
union all
select 4 as id,'2022-05-22' as dt
------------------
create table t1 as
select 1 as id,'2022-06-03' as dt1,'2022-05-03' as dt2
union all
select 2 as id,'2022-05-25' as dt, '2022-05-04' as dt2
union all
select 3 as id,'2022-03-01' as dt1, ' 2022-05-04' as dt2

其中mysql的实现方法:

select t.id,case when t1.id is not null then t.dt else null end as dt
from tjoin t1
on t.id = t1.id
and (t.dt=t1.dt1 or t.dt=t1.dt2)

hive中实现方法:

select id1 as id,max(case when id2 is not null then dt else null end) as dt
from 
(select cast(t.id as string) as id1,t.dt as dt,cast(t1.id as string) as id2
from tleft join t1
on t.id = t1.id
and t.dt=t1.dt1 
union 
select cast(t.id as string) as id1,t.dt as dt,cast(t1.id as string) as id2
from t
left join t1
on t.id = t1.id
and t.dt=t1.dt2 
) t
group by id1

结果如下:

OK
id      dt
1       2022-06-03
2       2022-05-04
3       NULL
4       NULL
Time taken: 3.343 seconds, Fetched: 4 row(s)

采用union或union all的方式代替关联中or的时候,根据上层所求的需要酌情去重。如果本题没有其他限制,只求id,那么采用union的方式就不要上层再去去重,本题中group by id1的方式就是为了去重,去不去重是根据需要和你需要展示的字段来看的。

针对本问题还有一种更优雅的实现方式,借助于loacte()的字符串匹配模式进行匹配,具体SQL如下:

select t.id
,case when locate(t.dt,concat_ws(',',t1.dt1,t1.dt2))>0 then t.dt else null end as dt
from t
left join t1
on t.id = t1.id

结果如下:

t.id    dt
2       2022-05-04
3       NULL
1       2022-06-03
4       NULL

2 小结

本文总结了hive  left join 时采用不等连接的实现方法,其归为两类一类是基于区间的不等连接,一类是基于or形式的匹配连接,两种连接采用不同的实现思路。基于区间的不等连接采用left join 的嵌套形式,目的是确保数据条数和主表一致,基于or形式的匹配连接,给出了两种思路,一种采用union的形式,一种采用locate()匹配形式,其中locate()的形式更优雅。

http://www.lbrq.cn/news/1074853.html

相关文章:

  • 宁波网站建设设计价格/网上怎么做推广
  • 网站建设包含哪些费用/首页关键词优化公司
  • 网站访客qq号码获取/网站seo设计
  • 正品手表官网/惠州百度seo地址
  • wordpress 设置显示中文/seo建站技术
  • 宁夏建设教育协会网站/广州公关公司
  • 做机械一般做那个外贸网站/推广网络广告
  • 学做网站的书哪些好/安徽网站关键词优化
  • 网站建设的主题什么比较好/如何做电商
  • 投资网站怎么做/百度地图轨迹导航
  • 移动互联网站开发/合肥关键词排名技巧
  • 贵阳网站建设网站制作/内存优化大师
  • html语言大型网站开发/seo网络推广是什么意思
  • 设计做网站/自媒体推广渠道
  • 邯郸建设信息网站/推广网址
  • 产品设计排名/seo综合查询接口
  • 网站建设图片/信阳网站seo
  • 优化型网站建设/seo整站优化解决方案
  • 提高网站流量原则/网络营销策划书1000字
  • 0539 网站/百度人工服务24小时电话
  • 做网站怎么还用身份证/关键词汇总
  • 任县城乡建设局网站/石家庄
  • 网页设计基础知识试题/seo内容优化是什么
  • 佛山网站建设网站制作公司/seo营销专员
  • 所得税汇算是在12366网站做吗/seo推广排名重要吗
  • 如何获取免费的wordpress/廊坊百度快照优化排名
  • 湛江网站制作公司/bt磁力猪
  • 基金会网站开发方案/公司网页怎么制作
  • 网站改版百度提交/关键词优化武汉
  • 深圳做百度网站/b站推广网站入口mmm
  • Azure DevOps 中的代理
  • .env 文件
  • Java高性能编程实践指南
  • K8S部署ELK(三):部署Elasticsearch搜索引擎
  • Node.js的用途和安装方法
  • 深入探索Weaviate:构建高效AI应用的数据库解决方案