我需要从Excel工作簿中读取数据,其中数据以这种方式存储:
Company Accounts
Company1 (#3000...#3999)
Company2 (#4000..4019)+(#4021..4024)
使用SSIS中的OLE DB目标的预期输出将是:
Company Accounts
Company1 3000
Company1 3001
Company1 3002
. .
. .
. .
Company1 3999
Company2 4000
Company2 4001
. .
. .
. .
Company2 4019
Company2 4021
. .
. .
Company2 4024
这让我感到困惑,我不知道如何开始处理这个问题。
有人对此有任何见解吗?
答案 0 :(得分:3)
首先,您必须将数据插入某个临时表。 Here are several ways。然后运行此查询:
with cte as (
select
company, replace(replace(replace(accounts,'(',''),')',''),'+','')+'#' accounts
from
(values ('company 1','#3000#3999'),('company 2','(#4000#4019)+(#4021#4024)')) data(company, accounts)
)
, rcte as (
select
company, stuff(accounts, ind1, ind2 - ind1, '') acc, substring(accounts, ind1 + 1, ind2 - ind1 - 1) accounts
from
cte
cross apply (select charindex('#', accounts) ind1) ca
cross apply (select charindex('#', accounts, ind1 + 1) ind2) cb
union all
select
company, stuff(acc, ind1, ind2 - ind1, ''), substring(acc, ind1 + 1, ind2 - ind1 - 1)
from
rcte
cross apply (select charindex('#', acc) ind1) ca
cross apply (select charindex('#', acc, ind1 + 1) ind2) cb
where
len(acc)>1
)
select company, accounts from rcte
order by company, accounts
option (maxrecursion 0)
答案 1 :(得分:3)
您可以添加脚本组件来实现此目的:
答案 2 :(得分:1)
假设工作表中有2个单元格,我发生的一般逻辑是将第二个单元格(每行)爆炸两次。第一遍使用+作为分隔符拆分字符串,并为每个公司返回一行或多行。使用..作为分隔符重复该逻辑,但每行返回2列。有了它,你可以循环或使用数字表来生成desierd集。如何最好地在ssis中这样做是一个我无法回答的问题,因为这不是一个经验领域。数字表方法相对简单和常见。
答案 3 :(得分:1)
首先,您需要一个分割字符串功能,或者根据您的数据,您需要一个自定义分割功能。 我的示例使用此dbo.DelimitedSplit8K
但正如我在分析excel数据后所说,我可能会创建一个自定义TVF。
其次,您必须拥有数字表,您可以创建自己的逻辑之一。 这是一次创造和人口
CREATE TABLE tblnumber (number INT PRIMARY KEY)
INSERT INTO tblnumber
SELECT ROW_NUMBER() OVER (
ORDER BY a.number
)
FROM master..spt_values a
,master..spt_values b
这只是一个基于您当前数据集的概念。
您需要将所有Excel数据拉入临时表。
create table #staging(Company varchar(50),Accounts varchar(50))
insert into #staging values
('Company1', '#3000...#3999')
,('Company2','#4000..4019)+(#4021..4024')
然后,
;with CTE as
(
select Company
,min(ca.Item) MinAcoount,max(ca.Item) MaxAcoount
from
(
select Company
,replace(replace(replace(replace(Accounts,'#','') ,')',''),'(',''),'+','.')Accounts
from #staging
)tbl
cross apply(Select * from dbo.DelimitedSplit8K(Accounts,'.'))ca
where ca.Item<>''
group by Company
)
select c.Company,number as Account from tblnumber n
inner join cte c on n.number>=MinAcoount and n.number<=MaxAcoount
因为我正在使用CTE。这只是为了理解。 帐户的清洁工作供您理解。