SQL进阶技巧:如何按照某个字段对数据进行动态分桶?

时间:2024-10-03 07:20:58

0 需求

如下表所示:

表中userid是唯一的, 并且每个code对应的name是一样的, 每个code对应的name字段的人数不一定一样.
需求:  将每个code对应的userid均分给name中的n1,n2,n3这种, 采用round_robin或者ranger的方式, 使用Hivesql实现 。

1 数据准备

(1)数据

user_id code name
1 X1 n1,n2,n3
2 X1 n1,n2,n3
3 X1 n1,n2,n3
4 X1 n1,n2,n3
5 X1 n1,n2,n3
6 X1 n1,n2,n3
7 X1 n1,n2,n3
8 X1 n1,n2,n3
9 X1 n1,n2,n3
10 X1 n1,n2,n3
11 X2 n4,n5,n6,n7
12 X2 n4,n5,n6,n7
13 X2 n4,n5,n6,n7
14 X2 n4,n5,n6,n7
15 X2 n4,n5,n6,n7
16 X3 n8,n9,n10,n11,n12,n13
17 X3 n8,n9,n10,n11,n12,n13
18 X3 n8,n9,n10,n11,n12,n13
19 X3 n8,n9,n10,n11,n12,n13
20 X3 n8,n9,n10,n11,n12,n13

(2)建表SQL

  1. drop table if exists dan_test.code
  2. CREATE TABLE dan_test.code (
  3. uesr_id string ,
  4. code string ,
  5. name string
  6. )
  7. ROW format delimited FIELDS TERMINATED BY "\t";

(3)加载数据

load data local inpath "/home/centos/dan_test/" into table code;

  (4) 查询数据  

  1. hive> select * from code;
  2. OK
  3. 1 X1 n1,n2,n3
  4. 2 X1 n1,n2,n3
  5. 3 X1 n1,n2,n3
  6. 4 X1 n1,n2,n3
  7. 5 X1 n1,n2,n3
  8. 6 X1 n1,n2,n3
  9. 7 X1 n1,n2,n3
  10. 8 X1 n1,n2,n3
  11. 9 X1 n1,n2,n3
  12. 10 X1 n1,n2,n3
  13. 11 X2 n4,n5,n6,n7
  14. 12 X2 n4,n5,n6,n7
  15. 13 X2 n4,n5,n6,n7
  16. 14 X2 n4,n5,n6,n7
  17. 15 X2 n4,n5,n6,n7
  18. 16 X3 n8,n9,n10,n11,n12,n13
  19. 17 X3 n8,n9,n10,n11,n12,n13
  20. 18 X3 n8,n9,n10,n11,n12,n13
  21. 19 X3 n8,n9,n10,n11,n12,n13
  22. 20 X3 n8,n9,n10,n11,n12,n13
  23. Time taken: 0.788 seconds, Fetched: 20 row(s)

2 数据分析

分桶本质是就是用ntile()函数,ntile()函数传入的是分桶的个数,现在分桶按照name字段中的个数动态分桶,此时只需要求一下name字段个数传进参数里面就可以,size(split(name,',')),按照id分桶,那么order by后面就是id。

分桶函数需要明确两点:

  • (1)分桶的个数是多少:分桶中传入的参数
  • (2)按照谁分桶:over()函数中order by该字段

此题需要按照每个code的 use_id进行 分桶,且分桶个数随name字段数改变,因而SQL如下

  1. select *
  2. ,ntile(size(split(name,','))) over(partition by code order by uesr_id) nt
  3. from code

 求的结果如下:

3 小 结

分桶函数是SQL中重要的函数,要灵活运用实际需求进行求解,分桶函数一般用于均分问题及求百分比问题,如果是百分比问题则分母就是桶的个数,另外需要搞清楚按谁分桶,谁就是窗口函数中order by需要跟的字段。