Complex SQL 2 | find new and repeat customers | SQL Interview Questions

Complex SQL 2 | find new and repeat customers | SQL Interview Questions

Ankit Bansal

2 года назад

87,479 Просмотров

Ссылки и html тэги не поддерживаются


Комментарии:

Proteeti Saikia
Proteeti Saikia - 10.11.2023 19:31

select * from customer_orders;

with cte as (select order_id,customer_id, order_date,order_amount, rank() over(partition by customer_id order by order_date) as visit_order
from customer_orders)
,
cte2 as(
select o.order_id, o.customer_id,o.order_date, o.order_amount,c.visit_order from
customer_orders o join cte c on o.order_id = c.order_id
order by order_date)

select order_date,
sum(case when visit_order = 1 then 1 else null end) as new_customer,
sum(case when visit_order >1 then 1 else null end) as repeated_customer
from cte2
group by order_date;

Ответить
Rahul dave
Rahul dave - 10.11.2023 09:27

My solution

with cte as(
select *, rank() over (partition by customer_id order by order_date) as rnk from customer_orders)
select order_date ,count(case when rnk = 1 then 1 else Null end ) as new_customer, count(case when rnk>1 then 1 else Null end) as repeat_customer
from cte
group by order_date

Ответить
fog
fog - 08.11.2023 19:00

finished watching

Ответить
VInuthna Gottapu
VInuthna Gottapu - 08.11.2023 18:13

with cte as(select *,min(order_date)over(partition by customer_id) as min_date
from customer_orders)
select order_date,
sum(case when order_date = min_date then 1 else 0 end) as new_customers,
sum(case when order_date != min_date then 1 else 0 end) as rep_customers
from cte
group by order_date ;

Ответить
Ankush sharma
Ankush sharma - 04.11.2023 15:02

with table_2 as(
with table_1 as
(SELECT customer_id, min(order_date) as first_visit from customer_orders
GROUP BY customer_id)
SELECT a.order_date, b.first_visit from customer_orders a INNER JOIN
table_1 b on a.customer_id = b.customer_id
)
SELECT order_date, sum(CASE
WHEN order_date = first_visit THEN 1
ELSE 0
END) as first_visit_flag,
sum(CASE
WHEN order_date != first_visit THEN 1
ELSE 0
END) as Repeat_visit_flag
from table_2
GROUP BY order_date;

Ответить
Ankush sharma
Ankush sharma - 04.11.2023 14:32

create table customer_orders (
order_id integer,
customer_id integer,
order_date date,
order_amount integer
);
insert into customer_orders values(1,100,cast('2022-01-01' as date),2000),(2,200,cast('2022-01-01' as date),2500),(3,300,cast('2022-01-01' as date),2100)
,(4,100,cast('2022-01-02' as date),2000),(5,400,cast('2022-01-02' as date),2200),(6,500,cast('2022-01-02' as date),2700)
,(7,100,cast('2022-01-03' as date),3000),(8,400,cast('2022-01-03' as date),1000),(9,600,cast('2022-01-03' as date),3000)
;

Ответить
Mahima Subramanyan
Mahima Subramanyan - 28.10.2023 01:48

New and repeat customers each day:

with cte_1
as
(
select customer_id,order_date,rank() over(partition by customer_id order by order_date) as rnk
from customer_orders
)
select order_date,
sum(case when rnk=1 then 1 else 0 end ) as new_customers,
sum(case when rnk>1 then 1 else 0 end ) as repeat_customers
from cte_1
group by order_date

Sales by New and repeat customers each day:


with cte_1
as
(
select customer_id,order_date,order_amount,rank() over(partition by customer_id order by order_date) as rnk
from customer_orders
)
select order_date,
sum(case when rnk=1 then order_amount else 0 end ) as new_customers_sales,
sum(case when rnk>1 then order_amount else 0 end ) as repeat_customers_sales
from cte_1
group by order_date

Enjoyed solving this question! Thanks Ankit Bhai :)

Ответить
Ashish Kumar
Ashish Kumar - 25.10.2023 17:41

df = df.withColumn('rn',expr('rank() over (partition by customer_id order by order_date )'))
df.filter(df.rn == 1).groupby('order_date').agg(count('order_date')).show()

Ответить
karthik morab
karthik morab - 23.10.2023 06:34

-- finding new and repeat customers including total_amount for newcustomers and repeat customers
with first_order as(
select customer_id,min(order_date) as first_order_date
from customer_orders
group by customer_id)
select co.order_date,
sum(case when co.order_date=fo.first_order_date then 1 else 0 end) as new_customer,
sum(case when co.order_date=fo.first_order_date then order_amount else 0 end) as new_cust_total,
sum(case when co.order_date!=fo.first_order_date then 1 else 0 end) as repeat_customer,
sum(case when co.order_date!=fo.first_order_date then order_amount else 0 end) as repeat_cust_total
from customer_orders co
join first_order fo on co.customer_id=fo.customer_id
group by co.order_date

Ответить
Taste Buds
Taste Buds - 21.10.2023 20:32

Here is My Solution
with cte1 as(
select customer_id, min(order_date) as fir_dt from customer_orders group by customer_id)
,cte2 as (
select co.customer_id,co.order_date,co.order_amount,cte1.customer_id as cust_id,cte1.fir_dt,
case when co.order_date = cte1.fir_dt then 1 else 0 end as new_cust,
case when co.order_date <> cte1.fir_dt then 1 else 0 end as repeat_cust,
case when co.order_date = cte1.fir_dt then co.order_amount else 0 end as new_cust_amt,
case when co.order_date <> cte1.fir_dt then co.order_amount else 0 end as repeat_cust_amt
from customer_orders co join cte1 on co.customer_id = cte1.customer_id)
select order_date,sum(new_cust) as new_cust, sum(repeat_cust) as repeat_cust, sum(new_cust_amt) as new_cust_amt, sum(repeat_cust_amt) as repeat_cust_amt
from cte2 group by order_date order by 1;

Ответить
arslan muhammad
arslan muhammad - 21.10.2023 20:28

select count(*) from(select customer_id,order_date,count(*) over (partition by customer_id order by order_id )as c
from Customer_order) as t1 where c<2 group by order_date this is only for new Customers

Ответить
Dave
Dave - 20.10.2023 19:10

Hi Sir, Solution to the amt for old and new customer

with cte as (
select customer_id, order_date,order_amount,
case when (customer_id, order_date) in (select customer_id, min(order_date)
from customer_orders group by customer_id) then 1 else 0 end as new_flag,
case when (customer_id, order_date) in (select customer_id, min(order_date)
from customer_orders group by customer_id) then 0 else 1 end as rep_flag
from customer_orders )
select order_date,
sum(case when new_flag=1 then order_amount else 0 end) as new_amount,
sum(case when rep_flag = 1 then order_amount else 0 end) as repeat_amount
from cte
group by order_date;


order_date new_amt repeat_amount
2022-01-01 6600 0
2022-01-02 4900 2000
2022-01-03 3000 4000

Ответить
Ayush Srivastav
Ayush Srivastav - 19.10.2023 06:53

with cte1 as(
select *,
row_number() over(partition by customer_id order by order_date) as rn
from customer_orders)
select order_date,
count(case when rn=1 then 1 else null end) as new_orders,
count(case when rn!=1 then 1 else null end) as repeat_orders
from cte1 group by order_date

Ответить
madhubanti deb
madhubanti deb - 18.10.2023 00:46

Select order_date, sum(case when rn =1 then 1 else 0 end) as fv ,
sum(case when rn !=1 then 1 else 0 end) as rv
from(
select *,
count(1) over(partition by customer_id order by order_date) as rn
from customer_orders
)A
group by order_date

it is giving same result

Ответить
ZEESHAN AHMED
ZEESHAN AHMED - 17.10.2023 20:33

Thank you very much Sir, for this practical question and your step by step explanation.

Ответить
Anusha M Krishna
Anusha M Krishna - 14.10.2023 21:50

with cte as(
select
customer_id,order_date,
FIRST_VALUE(order_date) over(PARTITION by customer_id order by order_date asc)fv from customer_orders)

select order_date,
SUM(case when fv=order_date then 1 else 0 end)new_customer,SUM(case when fv!=order_date
then 1 else 0 end)old_customer from cte group by order_date

Ответить
Javed Hassan Sheik
Javed Hassan Sheik - 14.10.2023 17:34

with A as
(select customer_id,min(order_date) as first_order_date
from customer_orders
group by customer_id),
B as
(select order_date,sum(order_amount) as all_customers_amount
from customer_orders group by order_date),
C as (SELECT A.first_order_date,
sum(co.order_amount) as new_customers_amount
FROM A join customer_orders co
on (A.first_order_date = co.order_date and A.customer_id = co.customer_id)
group by first_order_date)
select order_date,all_customers_amount,new_customers_amount,(all_customers_amount - new_customers_amount) as old_customers_amount
from B join C on B.order_date = c.first_order_date

Ответить
E 5330
E 5330 - 13.10.2023 19:12

Really good channel and informative videos.

Ответить
Sai B
Sai B - 09.10.2023 22:20

hi ankith this is also working
with cte as (
SELECT *,min(order_date) over (partition by customer_id) as first_date
FROM customer_orders as a
)
select order_date,count(case when order_date <> first_date then customer_id end) as repeat,
count(case when order_date = first_date then customer_id end) as new,
count(customer_id) as total
from cte
group by order_date

Ответить
Akash Gupta
Akash Gupta - 09.10.2023 20:00

Another approch using row number


WITH cte1 AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date) AS rn
FROM customer_orders
),
cte2 AS(
SELECT *,
CASE WHEN rn > 1 THEN 1 ELSE 0 END AS is_old,
CASE WHEN rn = 1 THEN 1 ELSE 0 END AS is_new
FROM cte1
)
SELECT order_date, sum(is_old) as old_customers, sum(is_new) as new_customers
FROM cte2
GROUP BY order_date
ORDER BY order_date

Ответить