ROW_NUMBER () с условием BIGQUERY - PullRequest
0 голосов
/ 06 декабря 2018

Я был бы очень признателен за помощь.У меня есть набор данных с покупками туров.У каждого тура есть Покупатель_Email и Event_Date, а также другие столбцы, не относящиеся к делу.Я хочу, чтобы поездка по столбцам определяла, является ли это событие новой поездкой или такой же поездкой.Чтобы идентифицировать новую покупку как новую поездку, разница между двумя Event_Dates должна составлять более 30 дней.Если нет, то этот тур считается такой же поездкой.В конце мне нужно узнать, сколько поездок совершил клиент, и сгруппировать покупки по поездкам.Я делаю запрос с ROW () NUMBER и вычисляю date_diff между первой покупкой и следующей покупкой.Я чувствую, что я очень близок, но мне нужна помощь, чтобы добавить столбец поездок.

Мне нужно что-то вроде этого: Желаемый столбец

В этом файле находитсяПример набора данных и нужного мне столбца: https://docs.google.com/spreadsheets/d/1ToNFQ9l2-ztDrN2zSlKlgBQk95vO6BnRv6VabWrHBmM/edit?usp=sharing Данные RAW - это первая вкладка, Результат запроса ниже на второй вкладке со столбцами оранжевого цвета, а последний столбец красного цвета - это столбец Яищу.

WITH NumberedDates AS (
SELECT
City
,Booking
,Purchase_Date
, Purchaser_Email
,Guest_Info
,Addr_1
,City_7
,State_Province
,Country
, Gross_Sales
, Event_Date
, Event_Name
, MIN(Event_Date) OVER (PARTITION BY Purchaser_Email) as minPurchDate
, ROW_NUMBER() OVER (PARTITION BY Purchaser_Email ORDER BY Event_Date) AS RowNo
FROM SalesEatingEurope.DymTable )



SELECT
n1.City
, n1.Booking
, n1.Purchase_Date
, n1.Purchaser_Email
, n1.Guest_Info
, n1.Addr_1
, n1.City_7
, n1.State_Province
, n1.Country
, n1.Gross_Sales
, n1.Event_Name
, n1.Event_Date
, n1.RowNo as TransactionNumber
, n2.Event_Date as PrevEventDate
, IFNULL(date_diff(EXTRACT(DATE FROM n2.Event_Date), EXTRACT(DATE FROM n1.Event_Date) ,day), 0)*-1 AS DaysSincePrevEvent
, n1.minPurchDate as FirstEvent
, IFNULL(date_diff( EXTRACT(DATE FROM n1.minPurchDate), EXTRACT(DATE FROM n1.Event_Date) ,day), 0)*-1 AS DaysSinceFirstEvent
FROM NumberedDates  AS n1
LEFT JOIN NumberedDates  AS n2
ON n1.Purchaser_Email = n2.Purchaser_Email
AND n1.RowNo = n2.RowNo + 1
ORDER BY n1.Purchaser_Email, n1.Event_Date

1 Ответ

0 голосов
/ 06 декабря 2018

Вы идете прямо.После разбиения и присвоения row_number() или rank() вы можете назначить логический параметр на основе условия двух покупок, запаздывающих с определенной дельтой.

Вот способ достижения этого:

with data as (
  select purchaser_email, event_date, rank() over (partition by purchaser_email order by event_date) as indx from (
    select 'abc_xyz@xyz.com' as purchaser_email, date('2018-10-15') as event_date union all
    select 'abc_xyz@xyz.com' as purchaser_email, date('2018-10-12') as event_date union all
    select 'abc_xyz@xyz.com' as purchaser_email, date('2018-10-19') as event_date union all
    select 'fgh_xyz@xyz.com' as purchaser_email, date('2018-10-03') as event_date union all
    select 'fgh_xyz@xyz.com' as purchaser_email, date('2018-10-10') as event_date union all
    select 'fgh_xyz@xyz.com' as purchaser_email, date('2018-11-26') as event_date union all
    select 'abc_xyz@xyz.com' as purchaser_email, date('2018-11-28') as event_date union all
    select 'abc_xyz@xyz.com' as purchaser_email, date('2018-12-30') as event_date union all
    select 'abc_xyz@xyz.com' as purchaser_email, date('2018-12-31') as event_date
  )
)
select purchaser_email, count(1) as order_count from (
  select purchaser_email, 
    d1, new_purchase, sum(case when new_purchase=true then 1 else 0 end) over (partition by purchaser_email order by d1) as purchase_count from (
    select 
      t1.purchaser_email, 
      t1.event_date as d1, 
      t2.event_date as d2, 
      t1.indx as t1i,
      t2.indx as t2i,
      case 
        when t2.event_date is null then true 
        when abs(date_diff(t1.event_date, t2.event_date, day)) >= 30 then true 
        else false end as new_purchase
      from data t1
      left join data t2 on t1.purchaser_email = t2.purchaser_email and t1.indx-1 = t2.indx
  )
  order by 1,2,3
)
where new_purchase = true
group by 1
order by 1
...