日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

oracle rollup分组没有数据时为0_Hive 入门数据分析基础 5

發(fā)布時(shí)間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 oracle rollup分组没有数据时为0_Hive 入门数据分析基础 5 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

六, 常用優(yōu)化技巧---主要內(nèi)容和思路來源:開課吧學(xué)習(xí)筆記

1, 用 group by 代替 distinct 去重

在數(shù)據(jù)量大, 重復(fù)值多時(shí), 能先使用 group by 去重的, 使用 group by 去重后再計(jì)算, 比之后再去重計(jì)算效率更高.

例如前面的例題中, 查詢 2019 年購買后又退款的用戶, 可以這樣優(yōu)化:

select a.user_name
from
(select user_name
from user_trade
where year(dt)=2019
group by user_name) a
join
(select user_name
from user_refund
where year(dt)=2019
group by user_name) b
on a.user_name=b.user_name;

2, 多維度聚合

需要對(duì)多個(gè)字段進(jìn)行聚合運(yùn)算, 一個(gè)字段一個(gè)字段的寫 SQL 計(jì)算, 不如使用多維度聚合計(jì)算語句: grouping sets, cube 和 rollup.

2.01, 分別查詢用性別, 城市, 等級(jí)分布:

select sex, city, level,
count(user_id)
from user_info
group by sex, city, level;

上述 sql 查詢出來的是同一性別, 不同城市, 不同等級(jí)的分布, 而我們需要的結(jié)果是三個(gè)字段的結(jié)果是分開的:

select sex, city, level,
count(user_id)
from user_info
group by sex, city, level
grouping sets (sex, city, level);
sexcitylevel_c3
NULLNULL133
NULLNULL226
NULLNULL330
NULLNULL444
NULLNULL530
NULLNULL632
NULLNULL735
NULLNULL834
NULLNULL930
NULLNULL1033
NULLbeijingNULL53
NULLchangchunNULL53
NULLguangzhouNULL55
NULLhangzhouNULL57
NULLshanghaiNULL61
NULLshenzhenNULL48
femaleNULLNULL177
maleNULLNULL150

a, grouping sets() 相當(dāng)于將不同 group by 聚合的結(jié)果進(jìn)行 union all, 可以在括號(hào)中指明聚合規(guī)則.

2.02, 查詢性別分布, 以及不同性別的城市分布:

select sex, city,
count(user_id)
from user_info
group by sex, city
grouping sets (sex, (sex, city));
sexcity_c2
femaleNULL177
femalebeijing26
femalechangchun32
femaleguangzhou30
femalehangzhou30
femaleshanghai36
femaleshenzhen23
maleNULL150
malebeijing27
malechangchun21
maleguangzhou25
malehangzhou27
maleshanghai25
maleshenzhen25

城市一列為 null 的是性別分布, 其他的是每個(gè)性別的城市分布.

b, with cube將分組聚合的所有維度都進(jìn)行計(jì)算:

2.03, 查詢性別, 城市, 等級(jí)各種組合的用戶分布情況:

-- 方法一
select sex, city, level,
count(user_id)
from user_info
group by sex, city, level
grouping sets (sex, city, level,
(sex, city), (sex, level), (city, level),
(sex, city, level));

-- 方法二
select sex, city, level,
count(user_id)
from user_info
group by sex, city, level
with cube;

方法二將所有用戶數(shù)進(jìn)行了統(tǒng)計(jì), 方法一沒有.

c, with rollup以最左側(cè)的字段為主, 進(jìn)行層級(jí)聚合, 結(jié)果是 with cube 的子集.

2.04, 查詢每個(gè)月的支付金額及每年的支付金額:

-- 方法一
select a.dt,
sum(a.year_amount),
sum(a.month_amount)
from
(select substr(dt, 1, 4) dt,
sum(pay_amount) year_amount,
0 month_amount
from user_trade
where dt>'0'
group by substr(dt, 1, 4)
union all
select substr(dt, 1, 7) dt,
0 year_mount,
sum(pay_amount) month_amount
from user_trade
where dt>'0'
group by substr(dt, 1, 7)
) a
group by a.dt;
a.dt_c1_c2
201724333973.600.00
2017-010.00241755.70
2017-020.002582410.60

第一列是年的總額.

-- 方法二
select year(dt) year,
month(dt) month,
sum(pay_amount)
from user_trade
where dt>'0'
group by year(dt), month(dt)
with rollup;
yearmonth_c2
NULLNULL62348041.30
2017NULL24333973.60
20171241755.70
201722582410.60

第一列是全部的總額, 第二列是年的總額. with rollup計(jì)算了全部的總額和以 year 字段為主的兩個(gè)維度 year, (year, month)的總額.

3, 轉(zhuǎn)換解題思路

前面的例題, 查詢 2017 和 2018 都購買的用戶, 可以如下優(yōu)化:

select a.user_name
from (select user_name,
count(distinct year(dt)) year_num
from user_trade
where year(dt) in (2017, 2018)
group by user_name) a
where a.year_num=2;

-- 還可再優(yōu)化
select user_name,
count(distinct year(dt)) year_num
from user_trade
where year(dt) in (2017, 2018)
group by user_name
having count(distinct year(dt))=2;

4, 有 union all 查詢時(shí), 開啟并發(fā)執(zhí)行

開啟參數(shù)設(shè)置: set hive.exec.parallel=true

查看是否設(shè)置成功: set hive.exec.parallel;

多臺(tái)服務(wù)器時(shí)開啟才有效.

5, 同一字段的數(shù)據(jù)展開, 或按分組歸類

有用戶購買的商品表 user_goods_category:

col_namedata_type
user_namestring
category_detailstring

部分?jǐn)?shù)據(jù):

Abbyclothes,food,electronics
Ailsabook,clothes,food
Albertclothes,electronics,computer

a, 同一字段的數(shù)據(jù)展開:

基表 lateral view explode(列表字段) 單列表 as 列名1

得到的結(jié)果是一個(gè)將 基表 的 列表字段 展開得到列名為 列名1 的 單列表 與 基表 合并的特殊表.

5.01, 查詢每個(gè)商品品類的購買用戶數(shù):

select b.category,
count(distinct a.user_name)
from user_goods_category a
lateral view explode(split(category_detail, ',')) b as category
group by b.category;
b.category_c1
book99
clothes110
computer99
electronics99
food105
shoes91

split()將字符串分割并以列表形式返回.

explode()將值為列表形式的字段展開成多行.

from語句后面得到的特殊表如下:

a.user_namea.category_detailb.category
Abbyclothes,food,electronicsclothes
Abbyclothes,food,electronicsfood
Abbyclothes,food,electronicselectronics
Ailsabook,clothes,foodbook
Ailsabook,clothes,foodclothes
Ailsabook,clothes,foodfood

b, 同一字段按分組歸類:

5.02, 查看每個(gè)商品品類都有哪些用戶購買:

select b.category,
collect_set(distinct a.user_name)
from user_goods_category a
lateral view explode(split(category_detail, ',')) b as category
group by b.category;
b.category_c1
book["Ailsa","Alexander",…(后面省略)]
clothes["Abby","Ailsa",...(后面省略)]

collect_set()將分組后分到同一組的值全部放到一個(gè)列表里顯示出來, 還可以再用 concat_ws('分隔符', ...) 將列表中的值連接成字符串.

6, 表連接優(yōu)化

  • 使用相同的連接鍵
    對(duì)3個(gè)以上表進(jìn)行 join 連接, on 條件使用相同的連接鍵, 只會(huì)產(chǎn)生一個(gè) MapReduce job.

  • 盡早進(jìn)行數(shù)據(jù)過濾
    例如數(shù)據(jù)只選擇需要的區(qū)段和字段, 分組去重等.

  • 邏輯過于復(fù)雜時(shí)引入中間表

7, 防止數(shù)據(jù)傾斜

數(shù)據(jù)傾斜: 任務(wù)執(zhí)行過程中, 大部分任務(wù)執(zhí)行完成, 少數(shù)任務(wù)一直在執(zhí)行中的情況.

  • 空值產(chǎn)生的數(shù)據(jù)傾斜
    表連接時(shí), 連接字段有空值, 增加空值過濾條件, 例如:on a.id=b.id and a.id is not null

  • 表連接時(shí), 連接字段數(shù)據(jù)類型不一致
    將數(shù)據(jù)類型轉(zhuǎn)換一致, 例如:on a.id=cast(b.id as string)

end

? ? ? ?點(diǎn)擊下方

總結(jié)

以上是生活随笔為你收集整理的oracle rollup分组没有数据时为0_Hive 入门数据分析基础 5的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。