Рассчитать счетчик прокрутки, используя оконные функции - PullRequest
0 голосов
/ 02 июля 2019

У меня есть таблица с заказами наших клиентов: order_date: дата заказов (которая не является уникальной, поскольку каждый заказ может иметь более одного продукта) customer_id: который не уникален

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

Я использую оконные функции в Postgres 11.2

CREATE TABLE "public"."orders" (
    "order_date" timestamp,
    "customer_id" integer
);

Вставка для данных:

INSERT INTO "public"."orders"("order_date", "customer_id") VALUES('2018-12-13 20:45:24.571964', 402) RETURNING "order_date", "customer_id";
INSERT INTO "public"."orders"("order_date", "customer_id") VALUES('2018-12-13 20:45:24.571964', 402) RETURNING "order_date", "customer_id";
INSERT INTO "public"."orders"("order_date", "customer_id") VALUES('2018-10-12 20:08:39.635959', 466) RETURNING "order_date", "customer_id";
INSERT INTO "public"."orders"("order_date", "customer_id") VALUES('2018-11-04 22:15:14.905851', 483) RETURNING "order_date", "customer_id";
INSERT INTO "public"."orders"("order_date", "customer_id") VALUES('2018-11-04 22:15:14.905851', 483) RETURNING "order_date", "customer_id";
INSERT INTO "public"."orders"("order_date", "customer_id") 

Я использовал эти коды для генерации того, что я хочу, но это не работает

select *,COALESCE(COUNT(*) OVER (partition by orders.customer_id order by orders.order_date range between interval '100 years' PRECEDING AND 
       CURRENT ROW EXCLUDE CURRENT ROW),0) AS 
       customer_orders_count_up_to_now,
       COALESCE(COUNT(*) OVER (partition by orders.customer_id order by 
       orders.order_date asc range BETWEEN interval '7 days' PRECEDING 
       AND CURRENT ROW EXCLUDE CURRENT ROW),0) AS 
       customer_orders_last_seven_days 
from orders

Я ожидаю, что выходные столбцы для customer_orders_count_up_to_now и customer_orders_last_seven_days будут составлять 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0 но фактические значения отличаются из-за дубликатов в order_date.

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

Я нашел решение, и в случае, если у других такая же проблема, я поделился здесь:

select *,COALESCE(COUNT(*) OVER (partition by orders.customer_id order by orders.order_date range between interval '100 years' PRECEDING AND 
   CURRENT ROW EXCLUDE CURRENT ROW),0) - COALESCE(COUNT(*) OVER (partition by orders.customer_id,orders.order_date order by orders.order_date range between interval '100 years' PRECEDING AND 
   CURRENT ROW EXCLUDE CURRENT ROW),0) AS 
   customer_orders_count_up_to_now,
   COALESCE(COUNT(*) OVER (partition by orders.customer_id order by 
   orders.order_date asc range BETWEEN interval '7 days' PRECEDING 
   AND CURRENT ROW EXCLUDE CURRENT ROW),0) - COALESCE(COUNT(*) OVER (partition by orders.customer_id order,orders.order_date by 
   orders.order_date asc range BETWEEN interval '7 days' PRECEDING 
   AND CURRENT ROW EXCLUDE CURRENT ROW),0) AS 
   customer_orders_last_seven_days from orders

Идея состоит в том, что для того, чтобы удалить дублирующийся счет из скользящего, мы должны вычесть количество вычисленных записей, имеющих дублирование в order_time, из вычисленного скользящего.

0 голосов
/ 02 июля 2019

Если я правильно понимаю, вы в основном хотите count(distinct) в качестве оконной функции. Postgres (пока) не поддерживает это. Но вы можете использовать select distinct в подзапросе:

select o.*,
       COALESCE(COUNT(*) OVER (partition by o.customer_id
                               order by o.order_date
                               range between interval '100 years' PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW),
                0) AS customer_orders_count_up_to_now,
       COALESCE(COUNT(*) OVER (partition by o.customer_id
                               order by o.order_date asc
                               range BETWEEN interval '7 days' PRECEDING AND CURRENT ROW EXCLUDE CURRENT ROW),
                0) AS customer_orders_last_seven_days 
from (SELECT DISTINCT o.customer_id, o.order_date from orders o) o
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...