2016-08-02 5 views
1

У меня есть схема с таблицей Customer и таблицей заказов. Клиент может разместить заказ в несколько дат. Мне нужно иметь предыдущий order_date для каждого order_date, соответствующего клиенту.Запрос, чтобы вывести дату предыдущего заказа, соответствующую клиенту?

Скажите, что заказчик разместил 4 заказа, затем для новейшего заказа (4-й заказ) - он должен вытащить текущий order_date и предыдущий order_date (3-й заказ). Для 3-го порядка, размещаемого клиентом, он должен вытащить 3-й заказ_дат как текущий order_date и предыдущий order_date (2-й порядок), так как он включен.

Я использую ниже запроса, чтобы получить предыдущий order_date, а затем присоединение с current_query, чтобы получить результат ::

select customerid, orderid, order_date as previous_order_date 
from (
    select c.customerid, o.orderid, o.order_date, 
     row_number() over (partition by c.customerid, o.orderid 
          order by o.order_date) rown 
    from customers c join orders o on c.customerid = o.customerid 
     ) a 
where rown = 2 

Но вопрос, я получаю одну дату, соответствующую CustomerID, тогда как требование - только предыдущий order_date, соответствующий текущему order_date для клиента.

Любое предложение поможет! Благодаря

ответ

2

Try с LAG() оконной функции в customerid:

select 
    c.customerid, o.orderid, o.order_date, 
    lag(o.order_date) over (partition by c.customerid order by o.order_date) AS prev_order_date 
from customers c 
join orders o on c.customerid = o.customerid 

Для самого раннего заказа каждого клиента prev_order_date будет нулевым.

результат

образца (не против OrderID, это просто для примера):

customerid | orderid | order_date | prev_order_date 
------------+---------+------------+----------------- 
      1 |  6 | 2015-02-08 | 
      1 |  2 | 2016-02-05 | 2015-02-08 
      1 |  3 | 2016-02-08 | 2016-02-05 
      1 |  1 | 2016-03-05 | 2016-02-08 
      2 |  5 | 2016-07-01 | 
      2 |  4 | 2016-07-08 | 2016-07-01 

Если один клиент может разместить один и тот же порядок в разные сроки (странно, но это, кажется, ваш случай) добавить o.orderid к статье PARTITION BY.

+1

Хорошая находка! Объяснение: http://docs.oracle.com/database/121/DWHSG/analysis.htm#CHDCBCGF «Поскольку функции обеспечивают доступ к нескольким строкам таблицы одновременно без самоподключения, они может повысить скорость обработки. Функция LAG обеспечивает доступ к строке с заданным смещением до текущей позиции, а функция LEAD обеспечивает доступ к строке с заданным смещением после текущей позиции ». –

0

К сожалению, LAG() не работал при использовании в узле SQL для целей отчетности. Я попытался использовать нижеследующий запрос и получил желаемый результат:

SELECT c.customer_code, o.customer_sid, o.order_id, o.order_no, 
     o.order_created_date, 
     (SELECT MAX (o1.order_created_date) 
      FROM d_customer c1 LEFT JOIN f_order o1 
       ON c1.customer_sid = 
            o1.customer_sid 
      WHERE c1.customer_sid = c.customer_sid 
      AND o1.order_created_date < o.order_created_date 
      AND EXISTS (SELECT 1 
          FROM f_invoice i 
          WHERE i.order_id = o1.order_id)) 
                AS prev_order_created_date, 
     t.financial_year, t.financial_month_no 
    FROM d_customer c JOIN f_order o 
     ON c.customer_sid = o.customer_sid 
     AND c.customer_type = 'PATIENT' 
     AND c.customer_country = 'UNITED STATES' 
     AND o.customer_type = 'PATIENT' 
     AND o.bill_to_country = 'UNITED STATES' 
     AND o.order_status = 'SHIPPED' 
     AND o.order_type = 'SALES' 
     AND o.order_group = 'REVENUE' 
    -- AND c.customer_code = '233379PT' 
     LEFT JOIN d_time t ON t.time_sid = o.order_created_date_sid 
ORDER BY order_created_date DESC