在SQL中选择当前列值与先前值

时间:2017-04-12 16:24:36

标签: sql sql-server sql-server-2012

我有一张订单表。在此表中,除了其他行之外,我还有ID(PK),客户ID,送货国家和订单日期

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

我需要选择客户之前订单与其最新订单的运输国家/地区不匹配的行。我还想在结果中看到2个不同的运输代码。

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

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

ID和OrderDate可用于确定事物的顺序。 ID是递增的数字,订单日期如下所示。

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

有什么建议吗?

这是一个让你入门的SQLFiddle:http://sqlfiddle.com/#!6/5d046/1/0

2 个答案:

答案 0 :(得分: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 :(得分: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 ;