sql - traer - oracle transponer registros columnas
Seleccionar filas en SQL donde el valor actual de la columna no coincide con el valor anterior (2)
Tengo una tabla de pedidos. En esta tabla, entre otras filas, tengo una identificación (PK), identificación del cliente, país de envío y fecha de pedido.
ID | CustomerId | ShippingCountry | OrderDate
1 | 111111 | DE | 2016-08-13
2 | 222222 | GB | 2016-08-17
3 | 111111 | ES | 2016-09-05
4 | 333333 | ES | 2016-10-25
5 | 444444 | US | 2016-10-26
6 | 555555 | FR | 2016-10-29
7 | 666666 | DE | 2016-11-04
8 | 111111 | DE | 2016-11-12
9 | 222222 | US | 2016-12-01
10 | 444444 | GB | 2016-12-01
11 | 555555 | FR | 2016-12-05
12 | 333333 | ES | 2016-12-15
Necesito seleccionar las filas donde el pedido anterior del cliente no coincide con el país de envío de su último pedido. También quiero ver los 2 códigos de envío diferentes en los resultados.
Usando el ejemplo anterior, quiero ver:
CustomerId | ShippingCountryLatest | ShippingCountryPrevious
111111 | DE | ES
222222 | US | GB
444444 | GB | US
ID y OrderDate se pueden usar para determinar el orden de las cosas. ID es un número creciente, la fecha del pedido es como dice.
La tabla con la que necesito ejecutar esto tiene alrededor de 500k filas.
¿Alguna sugerencia?
Aquí hay un SQLFiddle para que comiences: http://sqlfiddle.com/#!6/5d046/1/0
Use ROW_NUMBER
para dar el último registro n. ° 1 y el n. ° 2 anterior por cliente. Luego agregue por cliente y compare los dos valores.
select
CustomerId,
max(case when rn = 1 then ShippingCountry end) as ShippingCountryLatest,
max(case when rn = 2 then ShippingCountry end) as ShippingCountryPrevious
from
(
select
CustomerId,
ShippingCountry,
row_number() over (partition by CustomerId order by ID desc) as rn
from orders
) numbered
group by customerid
having
max(case when rn = 1 then ShippingCountry end) <>
max(case when rn = 2 then ShippingCountry end);
Tu violín de vuelta: http://sqlfiddle.com/#!6/5d046/13 :-)
Use lag()
:
select o.*
from (select o.*,
lag(shippingcountry) over (partition by customerid order by orderdate) as prev_shippingcountry
from orders o
) o
where prev_shippingcountry <> shippingcountry ;