2017-04-12 53 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可以接受他/她想要的任何答案。但我很好奇你爲什麼不接受這個答案,這似乎比其他方法簡單得多。 –

相關問題