как фильтровать данные в sql на основе процентиля - PullRequest
0 голосов
/ 24 марта 2019

У меня есть 2 таблицы, первая из которых содержит информацию о клиенте, такую ​​как идентификатор, возраст и имя.вторая таблица содержит их идентификатор, информацию о продукте, который они приобретают, и дату покупки (дата с 2016 по 2018 год)

Table 1
-------
customer_id
customer_age
customer_name
Table2
------
customer_id
product
purchase_date

Мой желаемый результат заключается в создании таблицы, содержащей имя_пользователя ипродукт, совершивший покупку в 2017 году и старше, чем 75% клиентов, совершивших покупку в 2016 году.

Ответы [ 2 ]

0 голосов
/ 24 марта 2019

Возраст - ужасное поле для включения в базу данных.Каждый день это меняется.У вас должна быть дата рождения или что-то подобное.

Чтобы получить 75% самое старое значение в 2016 году, есть несколько возможностей.Я обычно выбираю row_number() и count(*):

select min(customer_age)
from (select c.*,
             row_number() over (order by customer_age) as seqnum,
             count(*) over () as cnt
      from customers c join
      where exists (select 1
                    from customer_products cp
                    where cp.customer_id = c.customer_id and
                          cp.purchase_date >= '2016-01-01' and
                          cp.purchase_date < '2017-01-01'
                   )
      )
where seqnum >= 0.75 * cnt;

Затем, чтобы использовать это для запроса на 2017 год:

with a2016 as (
      select min(customer_age) as customer_age
      from (select c.*,
                   row_number() over (order by customer_age) as seqnum,
                   count(*) over () as cnt
            from customers c
            where exists (select 1
                          from customer_products cp
                          where cp.customer_id = c.customer_id and
                                cp.purchase_date >= '2016-01-01' and
                                cp.purchase_date < '2017-01-01'
                         )
            ) c
      where seqnum >= 0.75 * cnt
     )
select c.*, cp.product_id
from customers c join
     customer_products cp
     on cp.customer_id = c.customer_id and
        cp.purchase_date >= '2017-01-01' and
        cp.purchase_date < '2018-01-01' join
     a2016 a
     on c.customer_age >= a.customer_age;
0 голосов
/ 24 марта 2019

В зависимости от вашего вида SQL, вы можете получить квартили, используя более общую аналитическую функцию ntile. Это в основном добавляет новый столбец к вашему запросу.

SELECT MIN(customer_age) as min_age FROM (
SELECT customer_id, customer_age, ntile(4) OVER(ORDER BY customer_age) AS q4 FROM table1 
WHERE customer_id IN (
SELECT customer_id FROM table2 WHERE purchase_date = 2016)
) q 
WHERE q4=4

Возвращает наименьший возраст клиентов 4-го квартиля, который можно использовать в подзапросе для клиентов, совершивших покупки в 2017 году.

Аргумент к ntile - это количество сегментов, на которые вы хотите разделить. В этом случае 75% + равняется 4-му квартилю, поэтому 4 ведра в порядке. Предложение OVER() указывает, что вы хотите отсортировать (в нашем случае customer_age), а также позволяет нам разбивать (группировать) данные, если мы хотим, скажем, создать несколько рейтингов для разных лет или стран.

...