我有早起的习惯,每天早晨上班前的这段时间脑子非常清醒,这段时间我会用来充实自己。看到某个公众号发了一篇Hive的面试题的推文,顺手拿过来做了下。共计10道题,花了下班后的晚上和一个早晨的时间写完。

第一题

需求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
我们有如下的用户访问数据
userId visitDate visitCount
u01 2017/1/21 5
u02 2017/1/23 6
u03 2017/1/22 8
u04 2017/1/20 3
u01 2017/1/23 6
u01 2017/2/21 8
U02 2017/1/23 6
U01 2017/2/22 4
要求使用SQL统计出每个用户的累积访问次数,如下表所示:
用户id 月份 小计 累积
u01 2017-01 11 11
u01 2017-02 12 23
u02 2017-01 12 12
u03 2017-01 8 8
u04 2017-01 3 3

实现:
数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE prac.test1 ( 
userId string,
visitDate string,
visitCount INT )
ROW format delimited FIELDS TERMINATED BY "\t";
INSERT INTO TABLE prac.test1
VALUES
( 'u01', '2017/1/21', 5 ),
( 'u02', '2017/1/23', 6 ),
( 'u03', '2017/1/22', 8 ),
( 'u04', '2017/1/20', 3 ),
( 'u01', '2017/1/23', 6 ),
( 'u01', '2017/2/21', 8 ),
( 'u02', '2017/1/23', 6 ),
( 'u01', '2017/2/22', 4 );

查询SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
with t1 as(
select
userid,
date_format(regexp_replace(visitdate,'/','-'),'YYYY-MM') as vdate,
sum(visitcount) as vcount
from prac.test1
group by userid,date_format(regexp_replace(visitdate,'/','-'),'YYYY-MM')
)
select
userid,
vdate,
vcount,
sum(vcount) over (partition by userid order by vdate)
from t1;

第二题

需求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
有50W个京东店铺,每个顾客访客访问任何一个店铺的任何一个商品时都会产生一条访问日志,
访问日志存储的表名为Visit,访客的用户id为user_id,被访问的店铺名称为shop,数据如下:

u1 a
u2 b
u1 b
u1 a
u3 c
u4 b
u1 a
u2 c
u5 b
u4 b
u6 c
u2 c
u1 b
u2 a
u2 a
u3 a
u5 a
u5 a
u5 a
请统计:
(1)每个店铺的UV(访客数)
(2)每个店铺访问次数top3的访客信息。输出店铺名称、访客id、访问次数

数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
CREATE TABLE prac.test2 ( 
user_id string,
shop string
)
ROW format delimited FIELDS TERMINATED BY '\t';
INSERT INTO TABLE prac.test2 VALUES
( 'u1', 'a' ),
( 'u2', 'b' ),
( 'u1', 'b' ),
( 'u1', 'a' ),
( 'u3', 'c' ),
( 'u4', 'b' ),
( 'u1', 'a' ),
( 'u2', 'c' ),
( 'u5', 'b' ),
( 'u4', 'b' ),
( 'u6', 'c' ),
( 'u2', 'c' ),
( 'u1', 'b' ),
( 'u2', 'a' ),
( 'u2', 'a' ),
( 'u3', 'a' ),
( 'u5', 'a' ),
( 'u5', 'a' ),
( 'u5', 'a' );

查询SQL:
(1)每个店铺的UV(访客数)

1
2
3
4
5
select
shop,
count(distinct user_id) as user_cnt
from prac.test2
group by shop;

(2)每个店铺访问次数top3的访客信息。输出店铺名称、访客id、访问次数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
with t1 as(
select
shop,
user_id,
count(user_id) as cnt
from prac.test2
group by shop,user_id
)
select * from (
select
shop,
user_id,
cnt,
rank() over(partition by shop order by cnt desc) as rk
from t1
) as a
where rk<=3;

第三题

需求

1
2
3
4
5
已知一个表STG.ORDER,有如下字段:Date,Order_id,User_id,amount。
数据样例:2017-01-01,10029028,1000003251,33.57。
请给出sql进行统计:
(1)给出 2017年每个月的订单数、用户数、总成交金额。
(2)给出2017年11月的新客数(指在11月才有第一笔订单)

数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE prac.test3 ( 
dt string,
order_id string,
user_id string,
amount DECIMAL ( 10, 2 ) )
ROW format delimited FIELDS TERMINATED BY '\t';
INSERT INTO TABLE prac.test3 VALUES ('2017-01-01','10029028','1000003251',33.57);
INSERT INTO TABLE prac.test3 VALUES ('2017-01-01','10029029','1000003251',33.57);
INSERT INTO TABLE prac.test3 VALUES ('2017-01-01','100290288','1000003252',33.57);
INSERT INTO TABLE prac.test3 VALUES ('2017-02-02','10029088','1000003251',33.57);
INSERT INTO TABLE prac.test3 VALUES ('2017-02-02','100290281','1000003251',33.57);
INSERT INTO TABLE prac.test3 VALUES ('2017-02-02','100290282','1000003253',33.57);
INSERT INTO TABLE prac.test3 VALUES ('2017-11-02','10290282','100003253',234);
INSERT INTO TABLE prac.test3 VALUES ('2018-11-02','10290284','100003243',234);

查询SQL:
(1)给出 2017年每个月的订单数、用户数、总成交金额。

1
2
3
4
5
6
7
select
date_format(dt,'YYYY-MM') as mon,
count(order_id) as order_cnt,
count(user_id) as user_cnt,
sum(amount) as AMT
from prac.test3
group by date_format(dt,'YYYY-MM');

(2)给出2017年11月的新客数(指在11月才有第一笔订单)

1
2
3
4
5
6
7
8
9
10
11
12
13
with t1 as(
select
user_id
from prac.test3
where dt<to_date('2017-11-01')
)
select
date_format(dt,'YYYY-MM'),
count(1)
from prac.test3
where dt between '2017-11-01' and '2017-11-30'
and user_id not in (select t1.user_id from t1)
group by date_format(dt,'YYYY-MM')

不得不说答案上的这个写法真的很巧妙:

1
2
3
4
SELECT count(user_id)
FROM prac.test3
GROUP BY user_id
HAVING date_format(min(dt),'yyyy-MM')='2017-11';

第四题

需求:

1
有一个5000万的用户文件(user_id,name,age),一个2亿记录的用户看电影的记录文件(user_id,url),根据年龄段观看电影的次数进行排序?

数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
CREATE TABLE prac.test4user
(user_id string,
name string,
age int);

CREATE TABLE prac.test4log
(user_id string,
url string);

INSERT INTO TABLE prac.test4user VALUES
('001','u1',10)
,('002','u2',15)
,('003','u3',15)
,('004','u4',20)
,('005','u5',25)
,('006','u6',35)
,('007','u7',40)
,('008','u8',45)
,('009','u9',50)
,('0010','u10',65);
INSERT INTO TABLE prac.test4log VALUES
('001','url1')
,('002','url1')
,('003','url2')
,('004','url3')
,('005','url3')
,('006','url1')
,('007','url5')
,('008','url7')
,('009','url5')
,('0010','url1');

查询SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
with t1 as(
select
user_id,
count(1) as move_cnt
from prac.test4log
group by user_id
),t2 as(
select
user_id,
name,
(case when age>=0 and age<10 then '0-9'
when age>=10 and age<20 then '10-19'
when age>=20 and age<30 then '20-29'
when age>=30 and age<40 then '30-39'
when age>=40 and age<50 then '40-49'
when age>=50 and age<60 then '50-59'
when age>=60 and age<70 then '60-69'
when age>=70 and age<80 then '70-79'
else '80及以上' end) as age_peroid
from prac.test4user
)
select
t2.age_peroid,
sum(t1.move_cnt)
from t1
join t2
on t1.user_id=t2.user_id
group by age_peroid;

第五题

1
2
3
4
5
6
7
8
9
10
11
12
有日志如下,请写出代码求得所有用户和活跃用户的总数及平均年龄。(活跃用户指连续两天都有访问记录的用户)
日期 用户 年龄
2019-02-11,test_1,23
2019-02-11,test_2,19
2019-02-11,test_3,39
2019-02-11,test_1,23
2019-02-11,test_3,39
2019-02-11,test_1,23
2019-02-12,test_2,19
2019-02-13,test_1,23
2019-02-15,test_2,19
2019-02-16,test_2,19

数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CREATE TABLE prac.test5(
dt string,
user_id string,
age int)
ROW format delimited fields terminated BY ',';
INSERT INTO TABLE prac.test5 VALUES
('2019-02-11','test_1',23)
,('2019-02-11','test_2',19)
,('2019-02-11','test_3',39)
,('2019-02-11','test_1',23)
,('2019-02-11','test_3',39)
,('2019-02-11','test_1',23)
,('2019-02-12','test_2',19)
,('2019-02-13','test_1',23)
,('2019-02-15','test_2',19)
,('2019-02-16','test_2',19);

查询SQL:
求得所有用户和活跃用户的总数及平均年龄。(活跃用户指连续两天都有访问记录的用户)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
with t1 as(
select
count(1) as cnt_all,
avg(age) as avg_all
from(
select
user_id,
age
from prac.test5
group by user_id,age
)
),t2 as (
select
t4.user_id,
t4.age
from(
select
t3.user_id,
t3.age
from(
select
dt,
user_id,
age,
rk,
date_sub(dt,rk) as flag
from (
select
t0.dt,
t0.user_id,
t0.age,
rank() over(partition by t1.user_id order by t1.dt) as rk
from(
select
dt,
user_id,
age
from prac.test5
group by
dt,
user_id,
age
) as t0 -- 对用户访问表去重
)
) as t3
group by
t3.user_id,
t3.age,
t3.flag
having count(1)>=2
) as t4
group by
t4.user_id,
t4.age
)
select
count(t2.user_id),
avg(t2.age)
from t2
union all
select
cnt_all,
avg_all
from t1;

这道题比较复杂,难度在于如何求活跃用户,首先对用户活跃日志进行去重,每个用户每天只保留一条,然后对其按照用户分组,按照日期升序,使用row_number对其打上序号rk。
不难看出,如果是连续登录,那么日期dt和序号会是一个等差数列,故用登陆日期dt和序号做差,得到新的日期起别名flag。然后按照user_id和flag进行分组,如果一个分组内的数据量大于等于2,就说明这位用户是活跃用户。得到活跃用户,再一次进行去重操作,因为同一用户可能多次活跃,被判定为多次活跃用户。得到活跃用户再求他们的数量和平均年龄就比较简单了。

第六题

需求:

1
2
3
请用sql写出所有用户中在今年10月份第一次购买商品的金额,
表ordertable字段:
(购买用户:userid,金额:money,购买时间:paymenttime(格式:2017-10-01),订单id:orderid

数据准备:

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE prac.test6 (
userid string,
money decimal(10,2),
paymenttime string,
orderid string);

INSERT INTO TABLE prac.test6 VALUES
('001',100,'2017-10-01','123')
,('001',200,'2017-10-02','124')
,('002',500,'2017-10-01','125')
,('001',100,'2017-11-01','126');

查询SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
with t1 as(
select
userid,
money,
rank() over (partition by userid order by paymenttime) rk
from prac.test6
where paymenttime>='2017-10-01' and paymenttime<='2017-10-31'
)
select
userid,
money
from t1
where rk=1;

第七题

需求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
现有图书管理数据库的三个数据模型如下:
图书(数据表名:BOOK)
序号 字段名称 字段描述 字段类型
1 BOOK_ID 总编号 文本
2 SORT 分类号 文本
3 BOOK_NAME 书名 文本
4 WRITER 作者 文本
5 OUTPUT 出版单位 文本
6 PRICE 单价 数值(保留小数点后2位)
读者(数据表名:READER)
序号 字段名称 字段描述 字段类型
1 READER_ID 借书证号 文本
2 COMPANY 单位 文本
3 NAME 姓名 文本
4 SEX 性别 文本
5 GRADE 职称 文本
6 ADDR 地址 文本
借阅记录(数据表名:BORROW LOG)
序号 字段名称 字段描述 字段类型
1 READER_ID 借书证号 文本
2 BOOK_ID 总编号 文本
3 BORROW_DATE 借书日期 日期
(1)创建图书管理库的图书、读者和借阅三个基本表的表结构。请写出建表语句。
(2)找出姓李的读者姓名(NAME)和所在单位(COMPANY)。
(3)查找“高等教育出版社”的所有图书名称(BOOK_NAME)及单价(PRICE),结果按单价降序排序。
(4)查找价格介于10元和20元之间的图书种类(SORT)出版单位(OUTPUT)和单价(PRICE),结果按出版单位(OUTPUT)和单价(PRICE)升序排序。
(5)查找所有借了书的读者的姓名(NAME)及所在单位(COMPANY)。
(6)求”科学出版社”图书的最高单价、最低单价、平均单价。
(7)找出当前至少借阅了2本图书(大于等于2本)的读者姓名及其所在单位。
(8)考虑到数据安全的需要,需定时将“借阅记录”中数据进行备份,请使用一条SQL语句,在备份用户bak下创建与“借阅记录”表结构完全一致的数据表BORROW_LOG_BAK.井且将“借阅记录”中现有数据全部复制到BORROW_L0G_ BAK中。
(9)现在需要将原Oracle数据库中数据迁移至Hive仓库,请写出“图书”在Hive中的建表语句(Hive实现,提示:列分隔符|;数据表数据需要外部导入:分区分别以month_part、day_part 命名)
(10)Hive中有表A,现在需要将表A的月分区 201505 中 user_id为20000的user_dinner字段更新为bonc8920,其他用户user_dinner字段数据不变,请列出更新的方法步骤。(Hive实现,提示:Hlive中无update语法,请通过其他办法进行数据更新)

(1)数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
CREATE TABLE prac.book(book_id string,
`SORT` string,
book_name string,
writer string,
OUTPUT string,
price decimal(10,2));
INSERT INTO TABLE prac.book VALUES ('001','TP391','信息处理','author1','机械工业出版社','20');
INSERT INTO TABLE prac.book VALUES ('002','TP392','数据库','author12','科学出版社','15');
INSERT INTO TABLE prac.book VALUES ('003','TP393','计算机网络','author3','机械工业出版社','29');
INSERT INTO TABLE prac.book VALUES ('004','TP399','微机原理','author4','科学出版社','39');
INSERT INTO TABLE prac.book VALUES ('005','C931','管理信息系统','author5','机械工业出版社','40');
INSERT INTO TABLE prac.book VALUES ('006','C932','运筹学','author6','科学出版社','55');


-- 创建读者表reader

CREATE TABLE prac.reader (reader_id string,
company string,
name string,
sex string,
grade string,
addr string);
INSERT INTO TABLE prac.reader VALUES ('0001','阿里巴巴','jack','男','vp','addr1');
INSERT INTO TABLE prac.reader VALUES ('0002','百度','robin','男','vp','addr2');
INSERT INTO TABLE prac.reader VALUES ('0003','腾讯','tony','男','vp','addr3');
INSERT INTO TABLE prac.reader VALUES ('0004','京东','jasper','男','cfo','addr4');
INSERT INTO TABLE prac.reader VALUES ('0005','网易','zhangsan','女','ceo','addr5');
INSERT INTO TABLE prac.reader VALUES ('0006','搜狐','lisi','女','ceo','addr6');

-- 创建借阅记录表borrow_log

CREATE TABLE prac.borrow_log(reader_id string,
book_id string,
borrow_date string);

INSERT INTO TABLE prac.borrow_log VALUES ('0001','002','2019-10-14');
INSERT INTO TABLE prac.borrow_log VALUES ('0002','001','2019-10-13');
INSERT INTO TABLE prac.borrow_log VALUES ('0003','005','2019-09-14');
INSERT INTO TABLE prac.borrow_log VALUES ('0004','006','2019-08-15');
INSERT INTO TABLE prac.borrow_log VALUES ('0005','003','2019-10-10');
INSERT INTO TABLE prac.borrow_log VALUES ('0006','004','2019-17-13');

(2)找出姓李的读者姓名(NAME)和所在单位(COMPANY)

1
2
3
4
5
select
name,
company
from prac.reader
where name like 'li%';

(3)查找“高等教育出版社”的所有图书名称(BOOK_NAME)及单价(PRICE),结果按单价降序排序。

1
2
3
4
5
select
book_name,
price
from prac.book
order by price desc;

(4)查找价格介于10元和20元之间的图书种类(SORT)出版单位(OUTPUT)和单价(PRICE),结果按出版单位(OUTPUT)和单价(PRICE)升序排序。

1
2
3
4
5
6
7
select
sort,
output,
price
from prac.book
where price>=10 and price<=20
order by output,price;

(5)查找所有借了书的读者的姓名(NAME)及所在单位(COMPANY)。

1
2
3
4
5
6
select
b.name,
b.company
from borrow_log as a
left join reader as b
on a.reader_id=b.reader_id

(6)求科学出版社图书的最高单价、最低单价、平均单价。

1
2
3
4
5
6
select
max(price),
min(price),
avg(price)
from prac.book
where output='科学出版社';

(7)找出当前至少借阅了2本图书(大于等于2本)的读者姓名及其所在单位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
with t1 as(
select
reader_id,
count(1) as cnt
from borrow_log
group by reader_id
having cnt>=2
)
select
t2.name,
t2.company
from t1
left join reader as t2
on t1.reader_id=t2.reader_id;

(8)考虑到数据安全的需要,需定时将“借阅记录”中数据进行备份,请使用一条SQL语句,
在备份用户bak下创建与“借阅记录”表结构完全一致的数据表BORROWLOG_BAK.井且将“借阅记录”中现有数据全部复制到BORROW_L0G BAK中。

1
2
3
CREATE TABLE prac.borrow_log_bak AS
SELECT *
FROM prac.borrow_log;

(9)现在需要将原Oracle数据库中数据迁移至Hive仓库,请写出“图书”在Hive中的建表语句(Hive实现,提示:列分隔符|;数据表数据需要外部导入:分区分别以month_part、day_part 命名)

1
2
3
4
5
6
7
8
9
10
11
drop table if exists book2;
create external table book2(
BOOK_ID STRING COMMENT '总编号'
,SORT STRING COMMENT '分类号'
,BOOK_NAME STRING COMMENT '书名'
,WRITER STRING COMMENT '作者'
,OUTPUT STRING COMMENT '出版单位'
,PRICE STRING COMMENT '单价'
)COMMENT '图书表'
partitioned by(month_part string COMMENT '月分区',day_part string COMMENT '日分区')
row format delimited fields terminated by '|' stored as textfile;

(10)Hive中有表A,现在需要将表A的月分区 201505 中 user_id为20000的user_dinner字段更新为bonc8920,其他用户user_dinner字段数据不变,请列出更新的方法步骤。

  • 1.新建临时表写入更改过的数据
  • 2.把临时表数据写回原分区

第八题

需求:

1
2
3
4
5
6
7
有一个线上服务器访问日志格式如下(用sql答题)
时间 接口 ip地址
2016-11-09 14:22:05 /api/user/login 110.23.5.33
2016-11-09 14:23:10 /api/user/detail 57.3.2.16
2016-11-09 15:59:40 /api/user/login 200.6.5.166
… …
求11月9号下午14点(14-15点),访问/api/user/login接口的top10的ip地址

数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CREATE TABLE prac.test8(`date` string,
interface string,
ip string);

INSERT INTO TABLE prac.test8 VALUES
('2016-11-09 11:22:05','/api/user/login','110.23.5.23')
,('2016-11-09 11:23:10','/api/user/detail','57.3.2.16')
,('2016-11-09 23:59:40','/api/user/login','200.6.5.166')
,('2016-11-09 11:14:23','/api/user/login','136.79.47.70')
,('2016-11-09 11:15:23','/api/user/detail','94.144.143.141')
,('2016-11-09 11:16:23','/api/user/login','197.161.8.206')
,('2016-11-09 12:14:23','/api/user/detail','240.227.107.145')
,('2016-11-09 13:14:23','/api/user/login','79.130.122.205')
,('2016-11-09 14:14:23','/api/user/detail','65.228.251.189')
,('2016-11-09 14:15:23','/api/user/detail','245.23.122.44')
,('2016-11-09 14:17:23','/api/user/detail','22.74.142.137')
,('2016-11-09 14:19:23','/api/user/detail','54.93.212.87')
,('2016-11-09 14:20:23','/api/user/detail','218.15.167.248')
,('2016-11-09 14:24:23','/api/user/detail','20.117.19.75')
,('2016-11-09 15:14:23','/api/user/login','183.162.66.97')
,('2016-11-09 16:14:23','/api/user/login','108.181.245.147')
,('2016-11-09 14:17:23','/api/user/login','22.74.142.137')
,('2016-11-09 14:19:23','/api/user/login','22.74.142.137');

查询SQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
with t1 as(
select
date_format(`date`,'YYYY-MM-dd HH') as dt,
ip,
count(1) as cnt
from test8
where date_format(`date`,'YYYY-MM-dd HH')='2016-11-09 14'
group by date_format(`date`,'YYYY-MM-dd HH'),ip
)
select
dt,
ip,
rk
from(
select
dt,
ip,
rank() over(order by cnt desc) as rk
from t1
) as t2
where rk<=10;

第九题

需求:

1
2
3
4
5
6
7
8
有一个充值日志表credit_log,字段如下:
`dist_id` int '区组id',
`account` string '账号',
`money` int '充值金额',
`create_time` string '订单时间'

请写出SQL语句,查询充值日志表2019年01月02号每个区组下充值额最大的账号,要求结果:
区组id,账号,金额,充值时间

数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
CREATE TABLE prac.test9(
dist_id string COMMENT '区组id',
account string COMMENT '账号',
`money` decimal(10,2) COMMENT '充值金额',
create_time string COMMENT '订单时间');

INSERT INTO TABLE prac.test9 VALUES
('1','11',100006,'2019-01-02 13:00:01')
,('1','22',110000,'2019-01-02 13:00:02')
,('1','33',102000,'2019-01-02 13:00:03')
,('1','44',100300,'2019-01-02 13:00:04')
,('1','55',100040,'2019-01-02 13:00:05')
,('1','66',100005,'2019-01-02 13:00:06')
,('1','77',180000,'2019-01-03 13:00:07')
,('1','88',106000,'2019-01-02 13:00:08')
,('1','99',100400,'2019-01-02 13:00:09')
,('1','12',100030,'2019-01-02 13:00:10')
,('1','13',100003,'2019-01-02 13:00:20')
,('1','14',100020,'2019-01-02 13:00:30')
,('1','15',100500,'2019-01-02 13:00:40')
,('1','16',106000,'2019-01-02 13:00:50')
,('1','17',100800,'2019-01-02 13:00:59')
,('2','18',100800,'2019-01-02 13:00:11')
,('2','19',100030,'2019-01-02 13:00:12')
,('2','10',100000,'2019-01-02 13:00:13')
,('2','45',100010,'2019-01-02 13:00:14')
,('2','78',100070,'2019-01-02 13:00:15');

查询SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
with t1 as(
select
dist_id,
account,
sum(money) as sum_m
from prac.test9
where date_format(create_time,'yyyy-MM-dd')='2019-01-02'
group by
dist_id,
account
)
select
t2.dist_id,
t2.account,
t2.sum_m,
'2019-01-02'
from(
select
t1.dist_id,
t1.account,
t1.sum_m,
rank() over(partition by t1.dist_id order by sum_m desc) as rk
from t1
) as t2
where rk=1;

CREATE TABLE prac.test10(
`dist_id` string COMMENT '区组id',
`account` string COMMENT '账号',
`gold` int COMMENT '金币'
);

第十题:

需求:

1
2
3
4
有一个账号表如下,请写出SQL语句,查询各自区组的money排名前十的账号(分组取前10)
dist_id string '区组id',
account string '账号',
gold int '金币'

数据准备:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
INSERT INTO TABLE prac.test10 VALUES 
('1','77',18)
,('1','88',106)
,('1','99',10)
,('1','12',13)
,('1','13',14)
,('1','14',25)
,('1','15',36)
,('1','16',12)
,('1','17',158)
,('2','18',12)
,('2','19',44)
,('2','10',66)
,('2','45',80)
,('2','78',98);
select * from test10;

查询SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- 查询各自区组的money排名前十的账号(分组取前10)
with t1 as(
select
dist_id,
account,
gold,
rank() over(partition by dist_id order by gold desc) as rk
from prac.test10
)
select
t1.dist_id,
t1.account,
t1.gold,
t1.rk
from t1
where rk<=10;

这10道题并不难,和工作中的HiveSQL相比真的不算什么了,日拱一卒。加油!