SQLインタビューの質問-手書きのSQLケース(2))

目次

 

1.要件:各店舗のUV(訪問者数)と各店舗への訪問数top3

2. 2017年の各月の注文数、ユーザー数、合計取引額を入力します

3.すべてのユーザーとアクティブユーザーの総数と平均年齢を見つけます


1.要件:各店舗のUV(訪問者数)と各店舗への訪問数top3

50WのJDストアがあります。各顧客が任意のストアの製品にアクセスすると、アクセスログが生成されます。アクセスログに保存されるテーブルはVisit、訪問者のユーザーIDはuser_id、訪問したストアはshopと呼ばれます。

1)店舗あたりのUV(来場者数)

2)各店舗の訪問数上位3件の訪問者情報。ストア名、訪問者ID、訪問数を出力します

データ:

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

 最初にテーブルを作成します

create table visit(
user_id string,
shop string
) 
row format delimited fields terminated by '\t';

1.1店舗あたりのUV(訪問者数)

select
    shop,
    count(distinct user_id)
from visit
group by shop;

1.2各店舗への上位3回の訪問の訪問者情報。ストア名、訪問者ID、訪問数を出力します

1.2.1各ユーザーが各店舗にアクセスした回数を照会する

select
    shop,
    user_id,
    count(*) ct
from visit
group by shop,user_id;t1

1.2.2ユーザーの訪問数によって各店舗のランキングを計算する

select
     shop,
     user_id,
     ct, 
     rank() over(partition by shop order by ct) rk
from t1;t2

1.3各店舗の上位3つを取る

select
    shop,
    user_id,
    ct
from t2
where rk<=3

1.4最終SQL

select 
   shop,
   user_id,
   ct
from
 (select 
   shop,
   user_id,
   ct,
   rank() over(partition by shop order by ct) rk
from 
 (select 
   shop,
   user_id,
   count(*) ct
from visit
group by 
   shop,
   user_id)t1
)t2
where rk<=3;

2. 2017年の各月の注文数、ユーザー数、合計取引額を入力します

テーブルSTG.ORDERを指定すると、次のフィールドがあります:Date、Order_id、User_id、amount。統計のSQLを入力してください:データサンプル:2017-01-01、10029028、1000003251、33.57。

1)2017年の各月の注文数、ユーザー数、合計取引額を入力します。

2)2017年11月の新規顧客数を記入してください(11月の最初の注文のみを参照)

最初にテーブルを作成します

create table order_tab(
   dt string,
   order_id string,
   user_id string,
   amount decimal(10,2)
) 
row format delimited fields terminated by '\t';

2.1 2017年の各月の注文数、ユーザー数、合計取引額を記入してください

select
    date_format(dt,'yyyy-MM'),
    count(order_id),
    count(distinct user_id),
    sum(amount)
from order_tab
where
    date_format(dt,'yyyy')='2017'
group by
    data_format(dt,'yyyy-MM');

2.2 2017年11月の新規顧客数を考えると(11月の最初の注文を参照)

select
    count(user_id)
from
    order_tab
group by
    user_id
having
    date_format(min(dt),'yyyy-MM')='2017-11';

3.すべてのユーザーとアクティブユーザーの総数と平均年齢を見つけます

以下のようなログがあります。すべてのユーザーとアクティブユーザーの総数と平均年齢を取得するコードを記述してください。(アクティブユーザーとは、2日間連続してアクセスレコードがあるユーザーを指します)

データ

日付(dt)

ユーザー(user_id)

年齢

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

最初にテーブルを作成します

create table user_age(
      dt string,
      user_id string,
      age int
)
row format delimited fields terminated by ',';

3。1日付とユーザーでグループ化し、日付とランクで並べ替えます

select
    dt,
    user_id,
    min(age) age,
    rank() over(partition by user_id order by dt) rk
from user_age
group by
    dt,user_id;t1

3。2日付とランキングの差を計算する

select
    user_id,
    age,
    date_sub(dt,rk) flag
from t1;t2

3.3旅行の値が2以上のユーザー、つまり2日間連続してアクティブなユーザーをフィルタリングします

select
    user_id,
    min(age) age
from t2
group by
    user_id,
    flag
having
    coount(*)>=2;t3

3.4データの重複排除(ユーザーは複数の異なる時点で継続的にログインできます)

select
    user_id
    min(age) age
from t3
group by
    user_id;t4

3.5アクティブユーザーの数と平均年齢を計算します(2回の連続訪問)

select
    count(*) ct,
    cast(sum(age)/count(*) as decimal (10,2))
from t4;

3.6ユーザーに応じてグローバルデータセットを重複排除します

select
    user_id,
    min(age) age
from user_age
group by user_id;t5

3.7すべてのユーザーの数と平均年齢を計算する

select
    count(*) user_count,
    cast((sum(age)/count(*)) as decimal(10,1))
from t5;

3.8ステップ4とステップ6の2つのデータセットに対してunionall操作を実行します

select
    0 user_total_count,
    0 user_total_avg_age,
    count(*) twice_count,
    cast(sum (age)/count(*) as decimal(10,2))twice_count_avg_age
from(
  select
    user_id,
    min(age) age
from(
  select
    user_id,
    age,
    date_sub(dt,rk) flag
from(
  select
    dt,
    user_id,
    min(age) age,
    rank() over(partition by user_id order by dt) rk
  from
    user_age
  group by
    dt,user_id
)t1
)t2
group by
    user_id,flag
having
    count(*)>=2
)t3
group by user_id
)t4

union all

select
    count(*) user_total_count,
    cast((sum(age)/count(*)) as decimal(10,1)),
    0 twice_count,
    0 twice_count_avg_age
from(
  select
     user_id,
     min(age) age 
  from 
      user_age 
  group by 
      user_id
 )t5;t6

 

おすすめ

転載: blog.csdn.net/Poolweet_/article/details/109614982