2016-10-13 21 views
1

我卡住了。我需要進入客戶訂單數據庫,並確定每個月,客戶在13個月或更長時間不活動後下訂單。這將是約7萬年內約30,000個客戶和約355,000個訂單。識別客戶訂單之間的差距

例如...說客戶#123放置在接下來的幾個月的訂單:

CustomerNumber OrderMonth 
123    Jan 2010 
123    Feb 2010 
123    Apr 2010 
123    Jul 2011 
123    Jan 2013 
123    Feb 2013 
123    Aug 2015 

在這個例子中,我需要三行返回包含客戶123隨後的幾個月裏,因爲他們每個人在沒有訂單的情況下至少有13個月的差距。

CustomerNumber OrderMonth 
123    Jul 2011 
123    Jan 2013 
123    Aug 2015 

我在SQL Server 2008 R2上,因此Lead/Lag在工具箱中不可用。我通常可以發明某種解決方案,即使不是最實用/最有效的......但是這一個讓我難住了。任何想法,將不勝感激!

+0

什麼是ordermonth的數據類型?它是日期還是字符串? –

+0

這是一個開始的好地方。 http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

+0

看看[this](http://stackoverflow.com/questions/710212/is-there-a-way-to-access-the-previous-row-value-in-a-select-statement) – techspider

回答

1

找出如何與自己連接表的方式,但是每個訂單都與其先前的訂單相匹配。你沒有在那裏顯示所有列,但想象你有一個名爲OrderNumber的字段(可以計算)。然後你會寫這樣的東西:

SELECT ... 
FROM Orders a JOIN Orders b ON a.CutomerId = b.CustomerId AND a.OrderNumber = b.OrderNumber + 1 
WHERE DateDiff(a.OrderDate, b.OrderDate, M) > 13 
+0

還沒有嘗試過,但這應該做的伎倆....謝謝你讓我通過我的心理塊Zdravko! –

0

你可以隨時使用通用not exists

select * 
    from your_order_table o 
where not exists(select 1 
        from your_order_table o2 
        where o.CustomerNumber = o2.CustomerNumber 
         and o2.orderDate >= dateadd(month,-13,o.orderDate) 
         and o2.orderDate < o.orderDate) 
+0

會有很多月份組合滿足13個月的差距條件。不過,我們只應該看看前面的那一行。 –

+0

同意vkp ...感謝您的洞察力和建議 –

+0

@vkp - 'not exists'將導致查詢返回過去13個月內沒有該客戶的另一個訂單的任何訂單。沒有必要明確地找到最近的在先訂單(儘管數據庫可能會這樣做,假設適當的指數是爲了評估這一點)。 –

2
Declare @YourTable table (CustomerNumber int, OrderMonth Date) 
Insert Into @YourTable values 
(123,'2010-01-01'), 
(123,'2010-02-01'), 
(123,'2010-04-01'), 
(123,'2011-07-01'), 
(123,'2013-01-01'), 
(123,'2013-02-01'), 
(123,'2015-08-01') 

;with cteBase as (
    Select * 
      ,RowNr = Row_Number() over (Partition By CustomerNumber Order By OrderMonth) 
    From @YourTable 
) 
Select A.CustomerNumber 
     ,OrderMonth  = Left(DateName(MM,A.OrderMonth),3)+' '+cast(Year(A.OrderMonth) as varchar(4)) 
     ,NumberOfMonths = DateDiff(MM,B.OrderMonth,A.OrderMonth) 
    From cteBase A 
    Join cteBase B on (A.RowNr=B.RowNr+1) 
    Where DateDiff(MM,B.OrderMonth,A.OrderMonth)>=13 

返回

CustomerNumber OrderMonth NumberOfMonths 
123    Jul 2011 15 
123    Jan 2013 18 
123    Aug 2015 30 
+0

謝謝John,基於Zdravko之前的迴應,我完成了幾乎完全的事情。事後看起來很明顯,但我有一個完整的心理牆。 –

+0

@JasonSmith適合我們所有人。有時你只需要做一些無意義的任務,它會來找你。做得好。 –

0

您可以使用鉛來獲得差異(用於SQL Server> 2012)

;WITH cte 
AS (SELECT 
    *, LEAD(ordermonth, 1, ordermonth) OVER (PARTITION BY customerNumber ORDER BY ordermonth) AS nextordermonth 
FROM yourtable) 
SELECT CustomerNumber, nextordermonth 
FROM cte 
WHERE DATEDIFF(m, ordermonth, nextordermonth) > 13 

表結構

create table yourtable (CustomerNumber Int, OrderMonth date) 

Insert Into YourTable values 
(123,'2010-01-01'), 
(123,'2010-02-01'), 
(123,'2010-04-01'), 
(123,'2011-07-01'), 
(123,'2013-01-01'), 
(123,'2013-02-01'), 
(123,'2015-08-01') 
+0

將是我的第一個選擇/方法,但OP是在2008年,鉛/滯後不是他的選擇。 –