2017-04-12 71 views
3

我有一个订单表。在该表中,除其他行,我有一个ID(PK),客户ID,航运国家,订单日期在SQL中选择当前列值与先前值不匹配的行

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 

我需要选择行,其中客户以前的订单不符合他们的最新订单的航运国家。我也想在结果中看到两种不同的运费代码。

使用上面的例子,我想看到:

CustomerId | ShippingCountryLatest | ShippingCountryPrevious 
111111  | DE     | ES 
222222  | US     | GB 
444444  | GB     | US 

的ID和订购日期可以用来确定事物的顺序。 ID是一个递增的数字,订单日期如其所述。

我需要运行这个表的表有大约500k行。

有什么建议吗?

这里有一个SQLFiddle让你开始:http://sqlfiddle.com/#!6/5d046/1/0

+1

的SQL服务器的版本? –

+0

2012年以后的领先/滞后。 row_number()与cte否则将是一个好的开始。 – scsimon

+0

Cust 111111去DE> ES,然后ES> GB。为什么111111是DE> GB? –

回答

4

使用ROW_NUMBER给的最新记录#1和#以前的2%的客户。然后汇总每个客户并比较这两个值。

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); 

你拨弄回:http://sqlfiddle.com/#!6/5d046/13 :-)

1

使用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 ; 
+0

这两个答案的工作,但我打算标记这是正确的,根据文档,lag()是为了这个目的(我只是不知道它) – gfyans

+0

@gfyans:我们的两个查询是相当不同于另一个。你问最新的记录和前一个。戈登的查询不过是查看所有记录和以前的记录。只看最新的,它的前任不能单靠LAG来解决。 –

+0

@gfyans。 。 。你有没有发现这不起作用? OP可以接受他/她想要的任何答案。但我很好奇你为什么不接受这个答案,这似乎比其他方法简单得多。 –

相关问题