2015-07-21 13 views
0

我試圖導入到表後,解析在T-SQL一個BAIv2銀行文件。該文件由行組成,每行有兩個前導數字。如果行的前導數字碰巧是「88」,那麼它是一個「連續行」,並且意味着是前一行的擴展(以防止行在文件中變得太寬)。實施例下面的文件:SQL服務器串連某些Subsquent行到父行使用基於集合的解決方案

01,123456,123456,123456,1419,1,80,2/
02,123456,123456,1,123456,美元,2/
03,123456,美元,010,0 ,,, 015,0 ,,, 020,0 ,,, 025,0 ,,, 030,0 ,,, 040,0 ,,, 045,0 ,,/
88,050,0, ,, 055,0 ,,, 057,0 ,,, 060,0 ,,, 072,0 ,,, 074,0 ,,, 100,123456,1,270,123456,1,/
88400, 123456,35,470,123456,35,/
16,275,123456,S,123456,0,0 ,,/
88,ZBA XFER來自銀行賬戶123456
16,475,123456,Z,123456,123456/
88,CHECK-IRD
16,475,123456,Z,123456,123456/
88,登記IRD

如何使用基於集合的SQL查詢的行與一家領先追加「 88「到前一行?它看起來像一個基於XML的查詢可能工作。我能夠用複雜的循環和變量完成這個任務,但效率非常低,所以我想要一個基於集合的解決方案。任何幫助,將不勝感激。

我需要它看起來像這樣具有附加到以前行 「88」 記載:

01,123456,123456,123456,1419,1,80,2/
02,123456 ,123456,1,123456,美元,2/
03,123456,美元,010,0 ,,, 015,0 ,,, 020,0 ,,, 025,0 ,,, 030,0 ,,, 040,0 ,,, 045,0 ,,, 050,0 ,,, 055,0 ,,, 057,0 ,,, ...
16,275,123456,S,123456,0,0 ,,, ZBA XFER來自銀行帳戶123456
16,475,123456,Z,123456,123456,CHECK-IRD
16,475,123456,Z,123456,123456,CHECK-IRD

+0

如何表此刻設置? –

+0

它只有一個id列和一個名爲text_record的列來保存文件中的行。 –

回答

1

此,如果你在你的表

改寫爲遞歸CTE編輯有一個連續的int ID列纔有效。有可能是一個更簡單的方法,但它運行:

;with x (ID,txt,lvl)as 
(select ID,cast(txt as varchar(max)),1 as lvl 
from @table 
where ID = 1 
union all 
select a.ID 
,cast((case when left(a.txt,2) = '88' then cast(b.txt AS varchar(max)) else '' end)+ a.txt as varchar(max)) 
,case when left(a.txt,2) = '88' then b.lvl else b.lvl + 1 end 
from @table a 
inner join x b on a.ID = b.ID + 1) 

,y as (
select *,RANK() OVER(PARTITION BY lvl ORDER BY LEN(txt) desc) as rnk from x 
) 

select ID,REPLACE(REPLACE(txt,'/',''),'88,','') as txt from y where rnk = 1 
+0

這是非常接近的,但對於03記錄,它似乎沒有追加第88條記錄:88,400,123456,35,,470,123456,35,/ –

+0

對於任何父母,可以有多個連續記錄記錄。 –

+0

@JordanRovny檢查編輯。我跑了它,它運作 –

1

可以使用LEAD()LAG()窗函數來偷看之前或下一個記錄。 CTE會讓眼睛更容易一些,但我已經開始反其道而行了。

DECLARE @Test TABLE 
(
    ID INT, 
    Value NVARCHAR(50) 
) 
INSERT @Test SELECT 1,'111,111,111,111' 
INSERT @Test SELECT 2,'222,222,222,222' 
INSERT @Test SELECT 3,'88,222,222,222,222' 
INSERT @Test SELECT 4,'333,333,333,333' 
INSERT @Test SELECT 5,'88,333,333,333,333' 
INSERT @Test SELECT 6,'88,333,333,333,333' 
INSERT @Test SELECT 7,'444,444,444,444,444' 
INSERT @Test SELECT 8,'555,555,555,555,555' 


SELECT 
    Value=MAX(Value)  
FROM 
(
    SELECT 
     ContinuationGroup, 
     Value=SUBSTRING((
      SELECT 
       ','+Value 
      FROM 
      (
       SELECT 
        ID,Value,ContinuationGroup=SUM(ContinuationGroup) OVER (ORDER BY ID ROWS BETWEEN 99999 PRECEDING AND CURRENT ROW)  
       FROM 
       (
        SELECT 
         ID, Value= REPLACE(Value,'88,',''), ContinuationGroup=CASE WHEN CHARINDEX('88,',Value) >0 THEN 0 ELSE 1 END 
        FROM 
         @Test    
       )AS A  
      )AS B 
      WHERE 
       B.ContinuationGroup=Y.ContinuationGroup 
      ORDER BY ID FOR XML PATH('') 
     ), 3, 1000)  
    FROM 
    (
     SELECT 
      Value,ContinuationGroup=SUM(ContinuationGroup) OVER (ORDER BY ID ROWS BETWEEN 99999 PRECEDING AND CURRENT ROW)  
     FROM 
     (
      SELECT 
       ID,Value= REPLACE(Value,'88,',''),ContinuationGroup=CASE WHEN CHARINDEX('88,',Value) >0 THEN 0 ELSE 1 END 
      FROM 
       @Test 

     )AS Z 
    )AS Y 
)AS X 
GROUP BY 
    ContinuationGroup 
+0

這也非常接近,但第二個「88」記錄呢?任何父記錄可以有多個連續記錄。 –

+0

我看到添加了一個SUBSTRING(... FOR XML PATH(''))對於連接 –

+0

我試過運行這個,但運行時間超過30秒。我仍在嘗試。 –

相關問題