4. 旅行のシナリオ (Xidi がタクシーに乗る)
SQL174 2021 年の建国記念日に北京で 3 つ以上の注文を受けたドライバーの統計情報
- where の後の時間は、引用符で追加する必要があります。そうしないと、結果が報告されません。
たとえば、このコードの '2021-10-1' と '2021-10-7' の間の date(order_time) は、'2021- ではなく 2021-10-1 と 2021-10-7 と直接記述すると、 10-1 ' および '2021-10-7' には結果がありません。 - トピックでは、受注がキャンセルされた場合も、平均受注数にカウントされます。ドライバーが 3 つ以上の注文を受ける場合がありますが、3 つの注文はすべてキャンセルされます。したがって、if は使用しないでください。. . null、1、0 であり、これに似たステートメントをさらにフィルタリングします
select
city,
round(avg(order_cnt),3) as avg_order_num,
round(avg(fare_cnt),3) as avg_income
from(
select
city,
driver_id,
count(order_id) as order_cnt,
sum(fare) as fare_cnt
from tb_get_car_order
join tb_get_car_record using(order_id)
where date(order_time) between '2021-10-1' and '2021-10-7'
and city='北京'
group by driver_id
having count(order_id)>=3
) as a
group by city
注文がキャンセルされたドライバーの SQL175 平均評価
- 答えは2つの部分に分けられ、1つは選択された各ドライバーの状況、もう1つは全体の状況です。したがって、1 つのテーブルを使用して各ドライバーの状況を計算し、1 つのテーブルを使用して全体的な状況を計算し、次にすべてを結合して 2 つのテーブルをマージします。
- 平均スコアを求めることは難しくありませんが、難しいのは、注文がキャンセルされたドライバーを選別することと、キャンセルされなかったこれらのドライバーの注文の平均スコアです。したがって、where 条件ステートメントに別のクエリを追加して、10 月 21 日に注文がキャンセルされたドライバーのリストを除外し、外側のクエリ ステートメントを使用して平均スコアを計算できます。
(
select
driver_id,
round(avg(grade),1) as avg_grade
from tb_get_car_order
join tb_get_car_record using(order_id)
where start_time is not null
and driver_id in (
select distinct driver_id
from tb_get_car_order
where start_time is NULL
and date_format(order_time,'%Y-%m')='2021-10')
group by driver_id
order by driver_id
)
union all
(
select
'总体' as driver_id,
round(avg(grade),1) as avg_grade
from tb_get_car_order
join tb_get_car_record using(order_id)
where start_time is not null
and driver_id in (
select distinct driver_id
from tb_get_car_order
where start_time is NULL
and date_format(order_time,'%Y-%m')='2021-10')
)
SQL176 各都市の上位評価のドライバー情報
- 一番外側の層は結果を出力するために使用され、最初のサブクエリはソートと条件を設定するために使用され、2番目のサブクエリはさまざまな指標を計算するために使用されます。
- タイトルに「最高得点のドライバーが複数存在する場合は全て出力する」と書かれているため、ソートしてから絞り込むという方法は使えません。dense_rank を使用してソートし、最後にランクを 1 に設定できます。
- 1 日あたりの平均注文数と 1 日あたりのマイレージが得られるため、2 番目のサブクエリの order_time を date_foramat で日数に変換し、distinct, round(count(order_id)/count( distinct date_format(order_time
, "%Y-%m-%d")),1) as avg_order_num,
round(sum(mileage)/count(distinct date_format(order_time,"%Y-%m-%d")),3 ) as avg_mileage )
select
city,
driver_id,
avg_grade,
avg_order_num,
avg_mileage
from (
select
city,
driver_id,
avg_grade,
avg_order_num,
avg_mileage,
dense_rank() over(partition by city order by avg_grade desc) as rank_grade
from (
select
city,
driver_id,
round(avg(grade),1)avg_grade,
round(count(order_id)/count(distinct date_format(order_time,"%Y-%m-%d")),1) as avg_order_num,
round(sum(mileage)/count(distinct date_format(order_time,"%Y-%m-%d")),3) as avg_mileage
from tb_get_car_order
left join tb_get_car_record using(order_id)
group by city,driver_id
)as a
)as b
where rank_grade=1
order by avg_order_num
SQL177 国慶節期間中の過去 7 日間のキャンセルされた注文の平均数
- 日数が連続している場合、
つまり、9 月 25 日から 10 月 3 日まで毎日注文がある場合、ウィンドウ関数を使用して最初に日付を並べ替え、次に最初の 6 行と現在の行を取得できます。前の 2 行と現在の行の間の
行 日数が連続していない場合、途中で区切りがあります。
たとえば、9 月 26 日が 1 日中断され、10 月 2 日をカウントすると、9 月 25 日が統計に含まれます。現時点では、最初のメソッド メソッドを使用できます。 - 2番目の方法では、6行前は最初の6行を意味します.毎日注文がなく、日数が中断される場合、この方法は使用できません
select distinct date(order_time) dt,
round(
(select count(date(start_time))
from tb_get_car_order t2
where timestampdiff(day,date(order_time),date(t1.order_time)) between 0 and 6)/7
,2) as finish_num_7d,
round(
(select sum(if(start_time is null,1,0))
from tb_get_car_order t3
where timestampdiff(day,date(order_time),date(t1.order_time)) between 0 and 6)/7
,2) as cancel_num_7d
from tb_get_car_order t1
where date(order_time) between '2021-10-01' and '2021-10-03'
order by dt
select *
from (
select dt,
round(sum(finish_num) over (order by dt rows 6 preceding)/7,2) finish_num_7d,
round(sum(cancel_num) over (order by dt rows 6 preceding)/7,2) cancel_num_7d
from (
select distinct date(order_time) as dt,
count(start_time) as finish_num,
sum(if(start_time is null,1,0)) as cancel_num
from tb_get_car_order
group by dt
) t1
) t2
where dt between '2021-10-01' and '2021-10-03'
order by dt
SQL178 営業日の各時間帯の車両コール数、オーダーの待ち時間、および調整時間
- WEEKDAY() 関数は、指定された日付の曜日番号を返します。
注: 0=月曜日、1=火曜日、2=水曜日、3=木曜日、4=金曜日、5=土曜日、6=日曜日。 - time (列名) は時間 (時) を示します
select
(case when time(event_time)>='07:00:00' and time(event_time)<='09:00:00' then '早高峰'
when time(event_time)>='09:00:00' and time(event_time)<='17:00:00' then '工作时间'
when time(event_time)>='17:00:00' and time(event_time)<='20:00:00' then '晚高峰'
else '休息时间'
end ) as period,
count(order_time) as get_car_num,
round(avg(timestampdiff(second,event_time,order_time))/60,1) as avg_wait_time,
round(avg(timestampdiff(second,order_time,start_time))/60,1) as avg_dispatch_time
from tb_get_car_order
join tb_get_car_record using(order_id)
where weekday(event_time) between 0 and 4
group by period
order by get_car_num
SQL179 各都市で同時にバスを待っている人の最大数
-
ウィンドウ関数を使用して、時間ごとに異なる都市のバスを待っている人を並べ替え、同時にバスを待っている人の数を取得し、max を使用して同時にバスを待っている人の数を取得します。時間。(ウィンドウ関数 order by には累積効果があります。)
問題解決プロセス全体で必要な手順は 3 つだけです。
最初にサブテーブルを作成し、待機状態に入って待機状態から出るユーザーを定義し、テーブルを次のように接続します。並行して、
ウィンドウ関数を使って各都市の待機状況をUVに出し入れし、
最終的に各都市の最大UVを取り出すことができます。 -
ユーザーは次の 3 つの状態に分けられます:
状態 1:ドライバーが注文を受け入れる前にキャンセルした場合、order_id は生成されません. この場合、order_id IS NULL は end_time を記録します 状態
2:ドライバーは注文を受け入れた後にキャンセルし、その後、は搭乗時刻ではありません, start_time IS NULL を記録します finish_time 状態 3:
普通にバスに乗ります.
空、空でない場合は start_time (ifnull(式 1 , 式 2): 式 1 が空の場合は式 2 を返し、空でない場合は式 1 を返します) ユーザーが待機バスに入る 2 つのイベントを定義した後
、待っているバスを出て、すべてのテーブルを関連付け、ウィンドウ関数の並べ替えと累積を使用します。
上記の 3 つの状態の場合、UV=1 として状態に入り、UV=-1 のままにして、 -
タイトルには、「誰かが同時にバスを待っているのをやめ、誰かがバスを待ち始めた場合、バスを待っている人の数は最初に増加し、次に減少するように記録されます。」したがって、ウィンドウ関数も uv を逆順に並べ替えます。
with t1 as(
select city,
sum(uv)over(partition by city order by uv_time,uv desc) as uv_cnt #每个城市等车瞬时UV
from (
select city,
event_time uv_time,1 as uv
from tb_get_car_record #进入等车状态
union all
select city,end_time uv_time,-1 as uv
from tb_get_car_record
where order_id is null #接单前取消
union all
select city,
ifnull(start_time,finish_time) uv_time,-1 as uv
from tb_get_car_order
left join tb_get_car_record using(order_id)#接单后取消或上车
) as t
where date_format(uv_time,'%Y%m')='202110' #2021年10月
)
select city,max(uv_cnt) max_wait_uv
from t1
group by citY
order by max_wait_uv,citY;#排序先按照uv升序,uv一样按照城市升序