简体   繁体   中英

SQL left join same column and table

I have a customer order data and would like to do analysis on customer retention after price changes.

The order table is as follows:

customer_id order_number    order_delivered_date
   14156     R980193622        2/6/2020 14:51
  1926396    R130222714        22/5/2020 11:02
  1085123    R313065343        22/5/2020 14:50
  699858     R693959049        8/6/2020 17:03
  1609769    R195969327        3/6/2020 16:14
   14156     R997103187        27/6/2020 14:01
  1926396    R403942827        11/6/2020 14:42
  1926396    R895013611        8/7/2020 17:04

So, I would like to pull order in the period before new price. Assume the new price implementation is on 10/6/2020. I would like to do left join to order after the new price on the customer_id . Before is a set of data dated 10/5/2020 00:00:00 to 9/6/2020 23:59:59 while After is a set of data dated 10/6/2020 00:00:00 to 9/7/2020 23:59:59.

The desired table:

Before  After
14156   14156
1926396 1926396
1085123 Null
699858  Null
1609769 Null

If customer_id is found side by side it means they are retained. It should be simple...But I have been stucked.

EDIT: This is few code that I have been trying

First try:

 select ol2.customer_id as before, ol.customer_id as after
 from master.order_level ol, 
 left join master.order_level ol2
 on ol2.customer_id = ol.customer_id 
 where order_delivered_date between '2020-05-10 00:00:00' and '2020-07-09 23:59:59' and country_id = 2

Second try:

 SELECT ol.customer_id as before, ol2.customer_id as after
 FROM master.order_level ol,master.order_level ol2
 left join master.order_level
 ON ol.customer_id = ol2.customer_id
 WHERE ol.order_delivered_date between '2020-05-10 00:00:00' and '2020-06-09 23:59:59' and ol.country_id =2 and ol2.order_delivered_date between '2020-06-10 00:00:00' and '2020-07-09 23:59:59' and ol2.country_id =2

No need to do a join, you can just use you can do a simple group by and use case and aggregate functions. I also made a fiddle showing it in action here

SELECT customer_id, 
    CASE 
        WHEN MIN(order_delivered_date) < '3-15-2019' THEN customer_id
        ELSE NULL END customer_before,
    CASE
        WHEN MAX(order_delivered_date) >= '3-15-2019' THEN customer_id
        ELSE NULL END customer_after
FROM my_table
GROUP BY customer_id

there qyery will giva you results like this

customer_id     customer_before     customer_after
4               4                   (null)
1               1                   1
3               3                   (null)
2               2                   2
with before (customer_id) as
( select distinct customer_id from orders where order_delivered_date <= '10/06/2020'
),
after (customer_id) as
(select distinct customer_id from orders where order_delivered_date between '10/06/2020' and '09/07/2020')
select
     before.customer_id,
     after.customer_id
from before left outer join after on before.customer_id = after.customer_id

you can use union

select customer_id as before, null as after
from #order 
where order_delivered_date <'2020-06-10'
union 
select null as before, customer_id as after
from #order 
where order_delivered_date >='2020-06-10'

results

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM