我试图在导入到表后解析t-SQL中的BAIv2银行文件。该文件由行组成,每行有两个前导数字。如果行的前导数恰好是“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 ,, / <无线电通信/> 88,050,0 ,,, 055,0 ,,, 057,0 ,,, 060,0 ,,, 072,0 ,,, 074,0 ,,, 100,123456,1,270,123456,1,/
88,400,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,登记IRD
答案 0 :(得分:1)
仅当您的表格中有一个连续的int
ID列
编辑重写为递归CTE。可能有一种更简单的方法,但它运行:
;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
答案 1 :(得分: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