Относительно иметь количество (на тот день), счет за последние 10 дней и количество последних 20 дней для каждого транспортного средства - PullRequest
3 голосов
/ 12 марта 2020

Я пытаюсь увидеть продажи автомобиля за день и создать еще две колонки, в которых указывается количество продаж за последние 10 дней и количество продаж за последние 20 дней. Может быть несколько продаж для одного и того же дня и одного и того же автомобиля. Моя цель - взять «Определенное транспортное средство» и «Дату» и посмотреть их счет продаж.

Количество дней N должно быть относительно даты, представленной в этой строке.

Мои данные выглядят следующим образом:

 Vehicle_ID       Sales_Date
 X500             01/03/2020 02:00:00 PM
 X500             01/11/2020 05:00:00 PM
 X500             01/25/2020 06:00:00 PM
 X500             01/25/2020 01:00:00 PM
 X500             02/13/2020 06:00:00 PM
 X500             02/21/2020 02:00:00 PM

Моя целевая таблица должна выглядеть следующим образом:

 Vehicle_ID       Sales_Date     Sales_Count    Sales_Count_last_10     Sales_Count_last_20
 X500             01/03/2020         1                 1                      1
 X500             01/11/2020         1                 2                      2
 X500             01/25/2020         2                 2                      3
 X500             02/13/2020         1                 1                      4
 X500             02/21/2020         1                 2                      2

Я пробовал следующий запрос:

SELECT TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY') Sales_Date1, Vehicle_ID, 
       COUNT(*) OVER (PARTITION BY Vehicle_ID, TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY')) SALES_COUNTS,
       SUM(CASE WHEN TO_DATE(Sales_Date) BETWEEN TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY') - 10 AND TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY')
                    THEN 1 ELSE 0 END) OVER (PARTITION BY Vehicle_ID, TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY'))
                    Sales_Count_last_10,
      SUM(CASE WHEN TO_DATE(Sales_Date) BETWEEN TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY') - 20 AND TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY')
                    THEN 1 ELSE 0 END) OVER (PARTITION BY Vehicle_ID, TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY'))
                    Sales_Count_last_10
FROM TABLE1

Он просто создал те же значения для Sales_Count, Sales_Count_last_10 и Sales_Count_last_20. Это N-дневные столбцы были просто дубликатами Sales_Count

Я также попробовал следующий запрос.

SELECT TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY') Sales_Date1, Vehicle_ID, COUNT(*) SALES_COUNTS,
       SUM(CASE WHEN TO_DATE(Sales_Date) BETWEEN TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY') - 10 AND TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY')
                    THEN 1 ELSE 0 END) Sales_Count_last_10,
       SUM(CASE WHEN TO_DATE(Sales_Date) BETWEEN TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY') - 20 AND TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY')
                    THEN 1 ELSE 0 END) Sales_Count_last_20
FROM TABLE1
GROUP BY Vehicle_ID, TO_DATE(TO_CHAR(Sales_Date, 'MM/DD/YYYY'), 'MM/DD/YYYY')

Он показал тот же результат, что и предыдущий запрос. Дублирование Sales_Count для столбца N-дней.

Пожалуйста, помогите мне с этой проблемой.

Ответы [ 2 ]

1 голос
/ 12 марта 2020

Вы можете использовать выражение окна sum, чтобы указать, сколько дней назад вы хотите посмотреть.

С range between N preceding and current row, оно включает в себя все значения из текущей строки - от N до текущей

Что дает:

with rws as (
  select 'X500' vehicle_id, to_date ( '01/03/2020 02:00:00 PM', 'mm/dd/yyyy hh:mi:ss pm' ) sales_date from dual union all
  select 'Y300' vehicle_id, to_date ( '01/11/2020 05:00:00 PM', 'mm/dd/yyyy hh:mi:ss pm' ) sales_date from dual union all
  select 'Q240' vehicle_id, to_date ( '01/25/2020 06:00:00 PM', 'mm/dd/yyyy hh:mi:ss pm' ) sales_date from dual union all
  select 'Q240' vehicle_id, to_date ( '01/25/2020 01:00:00 PM', 'mm/dd/yyyy hh:mi:ss pm' ) sales_date from dual union all
  select 'F310' vehicle_id, to_date ( '02/13/2020 06:00:00 PM', 'mm/dd/yyyy hh:mi:ss pm' ) sales_date from dual union all
  select 'E990' vehicle_id, to_date ( '02/21/2020 02:00:00 PM', 'mm/dd/yyyy hh:mi:ss pm' ) sales_date from dual 
)  
  select distinct trunc ( sales_date ), vehicle_id, 
       count(*) over (
         partition by vehicle_id, trunc(sales_date) 
       )        sales_counts,
       count (*) over ( 
         order by trunc ( sales_date )
         range between 10 preceding and current row
       ) last_10,
       count (*) over ( 
         order by trunc ( sales_date )
         range between 20 preceding and current row
       ) last_20
from rws
order  by 1, 2

TRUNC(SALES_DATE)       VEHICLE_ID    SALES_COUNTS    LAST_10    LAST_20   
03-JAN-2020 00:00:00    X500                        1          1          1 
11-JAN-2020 00:00:00    Y300                        1          2          2 
25-JAN-2020 00:00:00    Q240                        2          2          3 
13-FEB-2020 00:00:00    F310                        1          1          3 
21-FEB-2020 00:00:00    E990                        1          2          2 

PS, если вы хотите удалить компонент времени из даты в Oracle Databse, просто trunc it. Гораздо проще, чем to_date(to_char(..., 'fmt'))!

0 голосов
/ 12 марта 2020

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

select
    vehicle_id,
    trunc(sales_date) sales_day,
    count(*) sales_count,
    sum(count(*)) over(
        order by trunc(sales_date)
        range between interval '10' day preceding and current row
    ) sales_count_last_10,
    sum(count(*)) over(
        order by trunc(sales_date)
        range between interval '20' day preceding and current row
    ) sales_count_last_20
from mytable
group by vehicle_id, trunc(sales_date)
order by sales_day
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...