首页 > 试题广场 >

统计用户从访问到下单的转化率

[编程题]统计用户从访问到下单的转化率
  • 热度指数:38337 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
现有某个商城部分订单数据,用户访问数据,如下所示:
订单信息表:order_tb(订单id:order_id,用户id:user_id,订单金额:order_price,订单创建时间:order_time)
order_id user_id order_price order_time
101 11 380 2022-09-01 09:00:00
102 12 200 2022-09-01 10:00:00
103 13 260 2022-09-01 12:00:00
104 11 100 2022-09-02 11:00:00
105 12 150 2022-09-02 12:00:00
106 12 1200 2022-09-02 13:00:00
107 11 60 2022-09-03 09:00:00
108 13 380 2022-09-03 09:30:00
访问信息表:visit_tb(访问信息id:info_id,用户id:user_id,访问时间:visit_time,离开时间:leave_time
info_id user_id visit_time leave_time
911 10 2022-09-01 08:00:00 2022-09-01 09:02:00
912 11 2022-09-01 08:30:00 2022-09-01 09:10:00
913 12 2022-09-01 09:50:00 2022-09-01 10:12:00
914 13 2022-09-01 11:40:00 2022-09-01 12:22:00
921 11 2022-09-02 10:30:00 2022-09-02 11:05:00
922 11 2022-09-02 12:00:00 2022-09-02 12:02:00
923 12 2022-09-02 11:40:00 2022-09-02 13:15:00
924 13 2022-09-02 09:00:00 2022-09-02 09:02:00
925 14 2022-09-02 10:00:00 2022-09-02 10:40:00
931 10 2022-09-03 09:00:00 2022-09-03 09:22:00
932 11 2022-09-03 08:30:00 2022-09-03 09:10:00
933 13 2022-09-03 09:00:00 2022-09-03 09:32:00
请统计该商城每天用户从访问到下订单的转化率。
要求输出:日期,转化率(该日下订单人数/访问人数,以百分数形式输出并四舍五入保留1位小数)
注:输出结果按照日期升序排序;
示例数据结果如下:
date cr
2022-09-01 75.0%
2022-09-02 50.0%
2022-09-03 66.7%

结果解释:
以2022-09-01为例,该日共计有user_id为10、11、12、13共计4名用户访问商城,
其中11、12、13共计3名用户下了订单,故转化率为3/4=75.0%;
其他结果同理。
示例1

输入

drop table if exists  `order_tb` ; 
CREATE TABLE `order_tb` (
`order_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`order_price` int(11) NOT NULL,
`order_time` datetime NOT NULL,
PRIMARY KEY (`order_id`));
INSERT INTO order_tb VALUES(101,11,380,'2022-09-01 09:00:00'); 
INSERT INTO order_tb VALUES(102,12,200,'2022-09-01 10:00:00'); 
INSERT INTO order_tb VALUES(103,13,260,'2022-09-01 12:00:00'); 
INSERT INTO order_tb VALUES(104,11,100,'2022-09-02 11:00:00'); 
INSERT INTO order_tb VALUES(105,12,150,'2022-09-02 12:00:00'); 
INSERT INTO order_tb VALUES(106,12,1200,'2022-09-02 13:00:00'); 
INSERT INTO order_tb VALUES(107,11,60,'2022-09-03 09:00:00'); 
INSERT INTO order_tb VALUES(108,13,380,'2022-09-03 09:30:00'); 

drop table if exists  `visit_tb` ; 
CREATE TABLE `visit_tb` (
`info_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`visit_time` datetime NOT NULL,
`leave_time` datetime NOT NULL,
PRIMARY KEY (`info_id`));
INSERT INTO visit_tb VALUES(0911,10,'2022-09-01 08:00:00','2022-09-01 09:02:00'); 
INSERT INTO visit_tb VALUES(0912,11,'2022-09-01 08:30:00','2022-09-01 09:10:00'); 
INSERT INTO visit_tb VALUES(0913,12,'2022-09-01 09:50:00','2022-09-01 10:12:00'); 
INSERT INTO visit_tb VALUES(0914,13,'2022-09-01 11:40:00','2022-09-01 12:22:00'); 
INSERT INTO visit_tb VALUES(0921,11,'2022-09-02 10:30:00','2022-09-02 11:05:00'); 
INSERT INTO visit_tb VALUES(0922,11,'2022-09-02 12:00:00','2022-09-02 12:02:00'); 
INSERT INTO visit_tb VALUES(0923,12,'2022-09-02 11:40:00','2022-09-02 13:15:00'); 
INSERT INTO visit_tb VALUES(0924,13,'2022-09-02 09:00:00','2022-09-02 09:02:00'); 
INSERT INTO visit_tb VALUES(0925,14,'2022-09-02 10:00:00','2022-09-02 10:40:00'); 
INSERT INTO visit_tb VALUES(0931,10,'2022-09-03 09:00:00','2022-09-03 09:22:00'); 
INSERT INTO visit_tb VALUES(0932,11,'2022-09-03 08:30:00','2022-09-03 09:10:00'); 
INSERT INTO visit_tb VALUES(0933,13,'2022-09-03 09:00:00','2022-09-03 09:32:00'); 

输出

date|cr
2022-09-01|75.0%
2022-09-02|50.0%
2022-09-03|66.7%
select date(ot.order_time) as date, concat(round(count(distinct ot.user_id)/count(distinct vt.user_id)*100,1),'%') as cr
from order_tb ot 
left join visit_tb vt on date(ot.order_time)=date(vt.visit_time)
group by date(ot.order_time)
order by date; -- 可以通过left join 连接限制条件


发表于 2025-01-07 22:57:06 回复(10)
select date(order_time) date, concat(round(count(distinct o.user_id)/count(distinct v.user_id)*100,1),'%') cr
from order_tb o join visit_tb v on date(o.order_time) = date(v.visit_time)
group by date
order by date

发表于 2025-02-18 14:48:08 回复(0)
with a as(
    select date(visit_time) vdate
    ,count(distinct user_id) vsum
    from visit_tb
    group by date(visit_time)
), --当日下单访问人数
b as(
    select date(order_time) odate
    ,count(distinct user_id) osum
    from order_tb
    group by date(order_time)
)  --当日下单人数
select odate as date
,concat(round((osum/vsum)*100,1),'%') cr
from a
inner join b on a.vdate=b.odate
group by odate;
发表于 2025-02-27 14:59:52 回复(0)
#创建两个临时表,分别统计每天下单用户数和浏览总人数,不考虑转化率为0的情况
WITH a AS(
    SELECT DATE(order_time) date,COUNT(DISTINCT user_id) or_cnt
    FROM order_tb
    GROUP BY 1
),
b AS(
    SELECT DATE(visit_time) date,COUNT(DISTINCT user_id) vi_cnt
    FROM visit_tb
    GROUP BY 1
)

SELECT date,CONCAT(ROUND((a.or_cnt/b.vi_cnt)*100,1),'%') cr
FROM a JOIN b USING(date)
ORDER BY 1

发表于 2025-11-01 23:07:25 回复(0)
select
date(time1) as date,
concat(round(count(time2)/count(time1)*100,1),'%') as cr
from(
select distinct
a.user_id,
a.visit_time as time1,
b.order_time as time2,
a.leave_time as time3
from visit_tb a
left join 
(select distinct
user_id,
order_time
from order_tb) as b
on a.user_id = b.user_id 
and b.order_time between a.visit_time and a.leave_time
) as c
group by date 为啥自测通过了,但是题目测试却通过不了?我感觉我这个也没毛病呀?有佬能解答一下吗

发表于 2025-06-09 20:38:54 回复(1)
较难题这么简单吗?我感觉自己强的可怕!!
WITH order_nums AS (
    SELECT 
        DATE_FORMAT(order_time, '%Y-%m-%d') AS `date`,
        COUNT(DISTINCT user_id) AS order_num
    FROM 
        order_tb
    GROUP BY 
        DATE_FORMAT(order_time, '%Y-%m-%d')
),
visit_nums AS (
    SELECT 
        DATE_FORMAT(visit_time, '%Y-%m-%d') AS `date`,
        COUNT(DISTINCT user_id) AS visit_num
    FROM 
        visit_tb
    GROUP BY 
        DATE_FORMAT(visit_time, '%Y-%m-%d')
)
SELECT
    `date`,
    CONCAT(ROUND(100 * order_num / visit_num, 1), '%') AS cr
FROM 
    order_nums
    LEFT JOIN visit_nums USING (`date`)
ORDER BY 
    `date`


发表于 2025-06-04 16:03:41 回复(1)
select
date(order_time) as date,
concat(round(count(distinct a.user_id)/count(distinct b.user_id) * 100 , 1) ,'%') as cr
from order_tb a
left join visit_tb b on
date(a.order_time) = date(b.visit_time)
group by
date(order_time)
order by
date(order_time) asc ; 这里面表和表的连接要用时间不是UID 因为UID要去算访问人数和下单人数,如果UID=UID 那就是100%
发表于 2025-03-23 17:05:03 回复(0)
with 
visit as (
    select date_format(visit_time, "%Y-%m-%d") as  visit_date, count(distinct user_id) as cnt
    from visit_tb
    group by date_format(visit_time, "%Y-%m-%d")
)
,
my_order_tb as(
    select date_format(order_time, "%Y-%m-%d") as order_date , count(distinct user_id) as cnt
    from order_tb
    group by date_format(order_time, "%Y-%m-%d")
)
,
t2 as (
    select v.visit_date as `date`, v.cnt as v_cnt , mot.cnt as o_cnt 
    from visit  v
    left join my_order_tb mot
    on v.visit_date=mot.order_date
)

select date, concat(round(o_cnt*100/v_cnt,1),"%") as cr
from t2
order by date asc

编辑于 2023-12-08 19:01:28 回复(0)
select date,concat(round(avg(tag)*100,1),"%") as cr
from 
(select 
distinct date(visit_time) as date
,user_id
,case when exists(select 1 from order_tb where user_id=x.user_id and date(order_time)=date(visit_time)) then 1 else 0 end as tag
from visit_tb x) e
group by 1
order by 1

发表于 2026-01-25 14:54:33 回复(0)
# 1.计算每日访问用户
with a as 
(select date(visit_time) day,count(distinct user_id)nums
from visit_tb
group by date(visit_time)),
# 2.计算每日支付用户
b as 
(select date(order_time) day,count(distinct user_id)nums
from order_tb
group by date(order_time))
## 3.计算每日转化率
select a.day date,concat(round(100*b.nums/a.nums,1),"%")cr
from a left join b on a.day = b.day
order by date

发表于 2026-01-24 17:11:09 回复(0)
with t1 as (
    select date_format(order_time, '%Y-%m-%d') as date,
    count(distinct user_id) as user_t1
    from order_tb ot
    group by date_format(order_time, '%Y-%m-%d')
),

t2 as(
    select date_format(visit_time, '%Y-%m-%d') as date,
    count(distinct user_id) as user_t2
    from visit_tb vt
    group by date_format(visit_time, '%Y-%m-%d')
)

select t1.date as date,
concat(round(user_t1 / user_t2 * 100, 1), '%') as cr
from t1
inner join t2
on t1.date = t2.date
order by date
发表于 2026-01-22 20:59:09 回复(0)
with t1 as (select distinct date(order_time) as 下单日期,user_id
from order_tb),
t2 as(select 下单日期,count(*) as 下单次数 from t1 group by 下单日期),
t3 as(select distinct date(visit_time) as 访问日期,user_id
from visit_tb),
t4 as(select 访问日期,count(*) as 访问次数 from t3 group by 访问日期)
select 下单日期 as date,concat(round((下单次数/访问次数)*100,1),'%') as cr
from t2
join t4 on t2.下单日期=t4.访问日期
order by date asc
发表于 2026-01-05 22:12:41 回复(0)
select  DATE(visit_time) as date,concat(round(count(distinct o.user_id)*100/count(distinct v.user_id),1),'%') as cr
from visit_tb v left join order_tb o
on v.user_id = o.user_id AND DATE(v.visit_time) = DATE(o.order_time)  group by  date(visit_time) order by date(visit_time)
发表于 2026-01-04 21:17:54 回复(0)
题目本身并不难,但是如果跨天访问第二天下单的比较难。如果本次访问是第一天的到退出时间是第二天内的下单,只要在本次访问内无论在前一天或者第二天的下单都算第一天的
发表于 2025-12-30 20:27:13 回复(0)
SELECT date(visit_time) `date`,
    concat(round(count(distinct ot.user_id)/count(distinct vt.user_id)*100,1),'%') cr
FROM visit_tb vt 
LEFT JOIN order_tb ot ON ot.user_id = vt.user_id AND date(ot.order_time) = date(vt.visit_time)
GROUP BY `date`
ORDER BY `date` 

发表于 2025-12-30 10:30:34 回复(0)
select
    visit_time date,
    concat(
        format((sum(if(order_time is null, 0, 1)) / count(1))*100,1),
        '%'
    ) cr
from
    (
        select distinct
            user_id,
            date_format(order_time, '%Y-%m-%d') order_time
        from
            order_tb
        group by
            user_id,
            order_time
    ) o
    right join (
        select distinct
            user_id,
            date_format(visit_time, '%Y-%m-%d') visit_time
        from
            visit_tb
        group by
            user_id,
            visit_time
    ) v on o.user_id = v.user_id
    and order_time = visit_time
group by
    date
order by
    date

发表于 2025-12-29 10:38:29 回复(0)
select t1.date, concat(round((gmrs / fwrs) * 100, 1), '%') cr
from (select date(order_time) date, count(distinct user_id) gmrs
      from order_tb ot
      group by date(order_time)) t1,
     (select date(visit_time) date, count(distinct user_id) fwrs from visit_tb vt group by date(visit_time)) t2
where t1.date = t2.date;
发表于 2025-12-28 14:47:12 回复(0)
with orderTable as(
select distinct
    user_id,
    date(order_time) as order_time
from order_tb),
visitTable as (
select 
    user_id,
    date(visit_time) as visit_time
from visit_tb
),
allInformation as(select distinct 
    visitTable.user_id,
    visit_time,
    order_time
from visitTable left join orderTable 
on visitTable.user_id = orderTable.user_id and orderTable.order_time = visitTable.visit_time)

select
    visit_time as date,
    concat(round(sum(case
    when order_time is not null then 1 else 0 end )/count(user_id)*100,1),"%")  as cr
    
from allInformation
group by visit_time
order by date

发表于 2025-12-26 21:45:07 回复(0)
没有什么是join,和窗口函数,和子查询查不出来的,有就是联表联的不给多
select
    tt1.date,
    concat(
        round(
            tt1.a / (
                select
                    count(distinct vv1.user_id)
                from
                    visit_tb vv1
                where
                    datediff(date_format(vv1.visit_time, '%Y-%m-%d'), tt1.date) = 0
            ) * 100,
            1
        ),
        '%'
    ) cr
from
    (
        select
            date_format(t.visit_time, '%Y-%m-%d') as date,
            count(*) a
        from
            (
                select distinct
                    v.*
                from
                    order_tb o
                    join visit_tb v on o.user_id = v.user_id
                    and o.order_time > v.visit_time
                    and o.order_time < v.leave_time
            ) t
        group by
            date_format(t.visit_time, '%Y-%m-%d')
    ) tt1



发表于 2025-12-16 23:56:34 回复(0)
去重之后连接:
WITH xd AS (
    select user_id,
        date_format(order_time,"%Y-%m-%d") as od
    from order_tb
    group by od,user_id
),
fw AS (
    select user_id,
        date_format(visit_time,"%Y-%m-%d") as vt
    from visit_tb
    group by vt,user_id

)
select vt as date,
    concat(round(sum(od is not null)/count(*)*100,1),"%") as cr
from fw f left join xd x on f.user_id = x.user_id and x.od = f.vt
group by vt
order by vt


发表于 2025-12-13 15:14:16 回复(0)