Преобразование строк в столбцы на основе ранга - PullRequest
0 голосов
/ 08 мая 2020

Я пытаюсь преобразовать строки в столбцы в зависимости от даты покупки (ранга) клиентов. Цель состоит в том, чтобы найти первую, вторую, третью, четвертую и пятую категорию продуктов, которые купил покупатель. Также хотелось бы знать, какой товар купил покупатель.

Таблица продаж

purchaseDate | productCategory | product      | customer_id | customer_phonenumber | customer_email
2020-05-05     Electronics       iPhone         A001          1234567890             aoo1@abc.com
2020-05-06     Clothing          T-shirt        A001          1234567890             aoo1@abc.com
2020-05-07     Electronics       Keyboard       A001          1234567890             aoo1@abc.com
2020-05-08     Accessories       iPhone Case    A001          1234567890             aoo1@abc.com

Результат

customer_id | customer_phoneNumber | customer_email | first_product_category | second_product_category | third_product_category | fourth_product_category | fifth_product_category  | first_product | second_product | third_product | fourth_product | fifth_product
A001          1234567890             a001@abc.com     Electonics               Clothing                    Electronics            Accessories               NULL                      iPhone          T-shirt          Keyboard        iPhone Case      NULL

Интересно, есть ли другой способ сделать это, поскольку мой текущий запрос занимает слишком много времени.

Вот мой запрос:

with ranked_order as (
    select 
        purchaseDate
        , productCategory
        , product
        , customer_id
        , customer_phonenumber
        , customer_email
        , row_number() over(partition by productCategory order by purchaseDate desc) rank
    from sales_table
    )

    select
        customer_id
        , customer_phonenumber
        , customer_email
        , max(case when rank = 1 then productCategory end) first_product_category
        , max(case when rank = 2 then productCategory end) second_product_category
        , max(case when rank = 3 then productCategory end) third_product_category
        , max(case when rank = 4 then productCategory end) fourth_product_category
        , max(case when rank = 5 then productCategory end) fifth_product_category
        , max(case when rank = 1 then product end) first_product
        , max(case when rank = 2 then product end) second_product
        , max(case when rank = 3 then product end) third_product
        , max(case when rank = 4 then product end) fourth_product
        , max(case when rank = 5 then product end) fifth_product
    from 
        ranked_order
    group by 1,2,3

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

Ниже для BigQuery Standard SQL

#standardSQL
SELECT 
  customer_id, 
  customer_phonenumber, 
  customer_email,
  top5[SAFE_OFFSET(0)].productCategory AS first_product_category,
  top5[SAFE_OFFSET(1)].productCategory AS second_product_category,
  top5[SAFE_OFFSET(2)].productCategory AS third_product_category,
  top5[SAFE_OFFSET(3)].productCategory AS fourth_product_category,
  top5[SAFE_OFFSET(4)].productCategory AS fifth_product_category,
  top5[SAFE_OFFSET(0)].product AS first_product,
  top5[SAFE_OFFSET(1)].product AS second_product,
  top5[SAFE_OFFSET(2)].product AS third_product,
  top5[SAFE_OFFSET(3)].product AS fourth_product,
  top5[SAFE_OFFSET(4)].product AS fifth_product
FROM (
  SELECT customer_id, customer_phonenumber, customer_email,
    ARRAY_AGG(STRUCT(productCategory, product) ORDER BY purchaseDate LIMIT 5) AS top5
  FROM `project.dataset.sales_table`
  GROUP BY customer_id, customer_phonenumber, customer_email
)
1 голос
/ 08 мая 2020

Я бы поместил значения в массивы:

select customer_id, customer_phonenumber, customer_email,
       array_agg(productCategory order by purchaseDate limit 5) as productCategorys_5,
       array_agg(product order by purchaseDate limit 5) as products_5
from sales_table
group by 1,2,3

Это помещает значения в массивы, а не в столбцы. Если у этого достаточно хорошая производительность, вы можете просто проиндексировать массивы, чтобы попасть в отдельные элементы (хотя я мог бы найти массивы более удобными).

...