2016-08-02 1 views
1

J'ai un schéma avec la table client et la table de commande. Un client peut passer commande à plusieurs dates. J'ai besoin d'avoir le order_date précédent pour chaque order_date correspondant à un client.Demande de tirer la date de la commande précédente correspondant à un client?

Dites un client placé 4 commandes, puis pour la commande la plus récente (4ème commande) - il doit tirer le order_date courant et le order_date précédent (3ème ordre). Pour la 3ème commande passée par le client, elle doit tirer 3rd order_date comme date de commande actuelle et date de commande précédente (2ème commande) comme ainsi de suite.

J'utilise ci-dessous requête pour obtenir order_date précédente, puis se joindre à current_query pour obtenir le résultat ::

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 

Mais la question est, je reçois une date unique correspondant à un customerid alors que l'exigence est - juste order_date précédent correspondant à la date de commande actuelle pour un client.

Toute suggestion aiderait! Merci

Répondre

2

Essayez avec fonction de fenêtre LAG() par 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 

Pour le premier ordre de chaque client prev_order_date sera nulle.

résultat de l'échantillon (ne pas l'esprit orderid, il est juste pour l'exemple):

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 

Si un client peut placer le même ordre dans les différentes dates (bizarre, mais cela semble être votre cas) ajouter o.orderid à la clause PARTITION BY.

+1

Bonne trouvaille! Explication: http://docs.oracle.com/database/121/DWHSG/analysis.htm#CHDCBCGF "Étant donné que les fonctions permettent d'accéder à plusieurs lignes d'une table en même temps sans une auto-jonction, elles La fonction LAG permet d'accéder à une ligne à un décalage donné avant la position actuelle, et la fonction LEAD donne accès à une ligne à un décalage donné après la position actuelle. " –

0

Malheureusement, LAG() ne fonctionnait pas lorsqu'il était utilisé dans un noeud SQL à des fins de création de rapports. J'ai essayé d'utiliser ci-dessous requête et obtenu le résultat souhaité:

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