0

在這種sqlfiddle ...瞭解遞歸CTE終止檢查

http://sqlfiddle.com/#!6/b6587/6

我收到以下錯誤....

終止聲明。報表完成前,最大遞歸100已用盡 。

我知道需要在CTE的第二個選擇的where子句中進行「終止檢查」。即使您取消註釋WHERE子句,也會得到相同的錯誤。

我只是想了解1)爲什麼需要...畢竟每個訂單行都與每個客戶行有關係,2)因爲需要「終止檢查」,所以它看起來像什麼讓這個例子工作。

順便說一句,我希望看到這個查詢的輸出如下。

1,'George', 'Patton','','' 
1,'','','<some date>', 'tank' 
1,'','','<some date>', 'plane' 
2,'Lewie', 'Puller','','' 
2,'','','<some date>', 'Rifle' 
2,'','','<some date>', 'Hand Grenade' 

順便說一句,隨時(不使用遞歸CTE)的其他方式來獲得這種結果發表評論,但還沒有使用遊標或臨時表。我想用基於集合的操作來做到這一點。

編輯

爲了記錄在案,我知道參加的工作,但我有問遞歸的理由。爲了給你上下文,我正在處理一個導出文件的結果集。每行只有一列稱爲LINE。此外,導出文件需要按照我的示例的順序輸出...細節需要在標題行下面,該模式需要重複...標題/細節...標題/細節。我認爲遞歸可以解決這個問題。但我知道簡單的連接也可以解決它,只要我可以得到行正確的順序...頭/細節...頭/細節,也許有一些方法來做一個列排序數字的輸出正確的方式。

我的導出不會依賴於調用應用程序來格式化數據......存儲過程需要格式化數據。

+2

你爲什麼在這裏使用遞歸? IT將無休止地循環查找相同的客戶編號,一遍又一遍地重複查看訂單表。看起來像一個簡單的連接會做你正在做的任何事情,因爲這個數據沒有層次關係。查看[這個sqlfiddle](http://sqlfiddle.com/#!6/b6587/9)使用「深度」來跟蹤遞歸步驟並將遞歸限制爲20. – JNevill

+0

它會超過遞歸的最大數量,它默認情況下是100.這是由於你有一個查詢問題 - 這是一個無限的遞歸,因爲@JNevill聲明 – scsimon

+0

任何反饋seth? – scsimon

回答

1

下面是使用日期的更好示例。假設我們想建立一個日期表。 2017年每月1行。我們創建一個@startDate作爲錨點,@endDate作爲終結點。我們將這些設置爲12個月,因爲我們想要一年。然後,遞歸將通過DATEADD函數向@startDate添加一個月,直到在WHERE子句中滿足終止符。我們知道這需要11次遞歸才能達到12個月......也就是11個月+開始日期。如果我們設置MAXRECURSION以任何低於11,則自11需要履行我們的遞歸CTEWHERE子句就會失敗,這是終結者..

declare @startDate datetime = '20170101' 
declare @endDate datetime = '20171201' 

;WITH Months 
as 
(
    SELECT @startDate as TheDate  --anchor 
    UNION ALL 
    SELECT DATEADD(month, 1, TheDate) --recursive 
    FROM Months 
    WHERE TheDate < @endDate   --terminator... i.e. continue until this condition is met 

) 


SELECT * FROM Months OPTION (MAXRECURSION 10) --change this to 11 

爲您的查詢,一個簡單的加入會足夠了。

select 
    firstName 
    ,lastName 
    ,orderDate 
    ,productID 
from 
    customers c 
inner join 
    orders o on o.customerID = c.id 

不過,我看你是想在一個奇怪的格式,它應該在什麼都報告您所使用的應用程序來處理退貨。這會讓你關閉而沒有遞歸。

with cte as(
select 
    firstName 
    ,lastName 
    ,orderDate 
    ,productID 
    ,dense_rank() over(order by c.id) as RN 
from 
    customers c 
inner join 
    orders o on o.customerID = c.id) 


select distinct 
    firstName 
    ,lastName 
    ,null 
    ,null 
    ,RN 
from 
    cte 
union all 
select 
    '' 
    ,'' 
    ,orderDate 
    ,productID 
    ,RN 
from 
    cte 
order by RN, firstName desc 
+0

,看着我的sqlfiddle,你能按照我要求的順序來獲得sql小提琴嗎?你的聯盟會返回所有的「標題」,然後返回所有的「細節」。 ORDER在這個問題中確實是一件很有意義的事情... header/details ... header/details。我認爲遞歸「可能」解決了這個問題。 –

+0

我很困惑@SethSpearman。我與工會的聯合會返回您的確切結果。 – scsimon

+0

對不起,我正在尋找小提琴。上面評論中的那個不是你的,我沒有注意到......但是確定你的代碼確實工作。這裏是一個小提琴... http://sqlfiddle.com/#!6/b6587/36 –