Bootstrap

SQL面试题(超详细)

1、表如下,请计算每个月每个部门评分大于等于90的人数,评分大于等于90的人数环比增长率,评分有提升的人数

年月

姓名

部门

评分

202101

张三

销售

90

202101

李四

技术

90

202101

王五

运营

80

202101

赵六

销售

70

202101

孙七

技术

95

202101

周八

运营

93

202101

吴九

销售

84

202101

郑十

技术

83

202102

张三

销售

95

202102

李四

技术

95

202102

王五

运营

95

202102

赵六

销售

95

202102

...

...

...

环比增长率=2月人数/1月人数-1

建表语句:

CREATE TABLE IF NOT EXISTS employee_performance (
    year_month string,
    name string,
    department string,
    score int
);
INSERT INTO TABLE employee_performance
VALUES
    ('202101', '张三', '销售', 90),
    ('202101', '李四', '技术', 90),
    ('202101', '王五', '运营', 80),
    ('202101', '赵六', '销售', 70),
    ('202101', '孙七', '技术', 95),
    ('202101', '周八', '运营', 93),
    ('202101', '吴九', '销售', 84),
    ('202101', '郑十', '技术', 83),
    ('202102', '张三', '销售', 95),
    ('202102', '李四', '技术', 95),
    ('202102', '王五', '运营', 95),
    ('202102', '赵六', '销售', 95);

解题步骤:

  • 先计算每个月每个部门评分大于等于90的人数
  • 计算每个部门上个月评分大于等于90的人数
  • 计算评分大于等于90的人数的环比增长率
  • 计算评分有提升的人数

解题过程:

(1)先计算每个月每个部门评分大于等于90的人数
select year_month,department,count(*) num from employee_performance where score >= 90 group by year_month,department order by year_month;
(2)计算每个部门上个月评分大于等于90的人数
with t1 as (
  select year_month,department,count(*) num from employee_performance where score >= 90 group by year_month,department order by year_month
),t2 as(select *,lag(num,1) over (partition by department order by year_month) lastnum from t1)
select * from t2;

(3)计算评分大于等于90的人数的环比增长率
with t1 as (
  select year_month,department,count(*) num from employee_performance where score >= 90 group by year_month,department order by year_month
),t2 as(select *,lag(num,1) over (partition by department order by year_month) lastnum from t1)
select *,num/lastnum-1 `环比增长率` from t2;

(4)计算评分有提升的人数
with t4 as (
    select *,lag(score,1) over(partition by name order by year_month) last_score from employee_performance
)select *,count() over() up_num from t3 where score>last_score;

(5)合并一下
with t1 as (
  select year_month,department,count(*) num from employee_performance where score >= 90 group by year_month,department order by year_month
),t2 as(select *,lag(num,1) over (partition by department order by year_month) lastnum from t1
),t3 as (
    select *,num/lastnum-1 `环比增长率` from t2
),t4 as (
    select *,lag(score,1) over(partition by name order by year_month) last_score from employee_performance
),t5 as (
    select year_month,count(*)  up_num from t4 where score>last_score group by year_month
)select t3.*,t5.up_num from t3 left join t5 on t3.year_month = t5.year_month;

2.交易记录表,表结构如下,请计算每个月各产品的购货人数,购货金额,购货金额排名,复购人数

(复购:前5个月曾购买此产品,本月有购买;购买: 购货金额大于0)

年月

订单号

原定单号

是否退货单

产品

购货人

金额

数量

202101

s100000

s100000

0

苹果

A

10

2

202101

s100001

s100000

1

苹果

A

-10

2

202101

s100002

s100002

0

西瓜

C

50

1

202106

s100003

s100003

0

西瓜

C

50

1

202102

...

...

...

...

...

...

...

建表语句:

CREATE TABLE zuoye2 (
    year_month STRING,
    order_id STRING,
    original_order_id STRING,
    is_return INT,
    product STRING,
    buyer STRING,
    amount INT,
    quantity INT
);
INSERT INTO zuoye2 (year_month, order_id, original_order_id, is_return, product, buyer, amount, quantity)
VALUES
('202101', 's100000', 's100000', 0, '苹果', 'A', 10, 2),
('202101', 's100001', 's100000', 1, '苹果', 'A', -10, 2),
('202101', 's100002', 's100002', 0, '苹果', 'C', 50, 1),
('202106', 's100003', 's100003', 0, '西瓜', 'C', 50, 1);

解题步骤:

  • 计算每个月各产品的购货人数,购货金额
  • 计算购货金额排名
  • 计算复购人数

解题过程:

(1)计算每个月各产品的购货人数,购货金额
select year_month,product,count(distinct buyer),sum(amount) sum_amo from zuoye2 group by year_month,product
(2)计算购货金额排名
with t1 as (
    select year_month,product,count(distinct buyer),sum(amount) sum_amo from zuoye2 group by year_month,product
),t2 as (
    select *,dense_rank() over (partition by year_month order by sum_amo desc ) rank from t1
)select * from t2;

 

(3)计算复购人数
with t1 as (
    select year_month,product,buyer,count(distinct buyer) over(partition by year_month,product) con1,sum(amount) over(partition by year_month,product) sum_amo from zuoye2
),t2 as (
    select *,dense_rank() over (partition by year_month order by sum_amo desc ) rank from t1
),t3 as (select tb1.*, tb2.buyer as buyers
         from t2 tb1
                  left join t2 tb2 on tb2.year_month >= date_format(
                 add_months(from_unixtime(unix_timestamp(tb1.year_month, 'yyyyMM')), -5), 'yyyyMM')
             and tb2.year_month < tb1.year_month and tb1.product = tb2.product and tb1.buyer = tb2.buyer
),t4 as(select year_month,con1,sum_amo,rank,count(*) over(partition by year_month) `复购人数` from t3 where buyers is not null)
select t2.year_month,t2.product,t2.con1,t2.sum_amo,t2.rank,t4.`复购人数` from t2 left join t4 on t2.year_month = t4.year_month;

3.交易记录表,表结构如下,请计算每个月购货人同时购买苹果和西瓜的金额(购货人单月只购买其中一样不计算,需在一个月内两个都购买)

年月

订单号

原定单号

是否退货单

产品

购货人

金额

数量

202101

s100000

s100000

0

苹果

A

10

2

202101

s100001

s100000

1

苹果

A

-10

2

202101

s100002

s100002

0

西瓜

C

50

1

202101

s100003

s100003

0

苹果

C

10

1

202102

...

...

...

...

...

...

...

建表语句:

CREATE TABLE IF NOT EXISTS orders_info (
    year_month string,
    order_number string,
    original_order_number string,
    is_return_order int,
    product string,
    purchaser string,
    amount double,
    quantity int
);

INSERT INTO TABLE orders_info
VALUES
    ('202101','s100000','s100000',0,'苹果','A',10.0,2),
    ('202101','s100001','s100000',1,'苹果','A',-10.0,2),
    ('202101','s100002','s100002',0,'西瓜','C',50.0,1),
    ('202101','s100003','s100003',0,'苹果','C',10.0,1);

解题步骤:

  • 计算出每个月既购买苹果又购买西瓜的人,并求金额

解题过程:

(1)计算出每个月既购买苹果又购买西瓜的人,并求金额
with t1 as (
    select *,sum(amount) over(partition by year_month,purchaser,product) sum_money from orders_info
), t2 as(select *,count(*) over(partition by year_month,purchaser) con from t1 where sum_money > 0 and product = '苹果' or product = '西瓜'
) select year_month,purchaser,sum(amount)  sum_amount from t2 where con == 2 group by year_month, purchaser;

;