我有水平表格(Table1),我需要它将它转换为(Table2)
表1:
CEO SALESMAN PRODUCT(1) PRODUCT(2) PRODUCT(3) PRODUCT(4) PRODUCT(5) ... PRODUCT(N)
------ ---------- ---------- ---------- ---------- ---------- ---------- ----------
MIKE ANDERSON 76787,00 19388,00 0,00 2723,00 217,00 6581,00
JOHN ANGELA 0,00 0,00 73088,00 0,00 0,00 0,00
JACK JEFF 24716,00 0,00 2995,00 0,00 0,00 0,00
STUART MICHAEL 0,00 23338,00 42656,00 0,00 0,00 0,00
表2:
CEO SALESMAN PRODUCTS VALUE
------- ----------- ---------- --------
MIKE ANDERSON PRODUCT(1) 76787,00
JOHN ANGELA PRODUCT(1) 0,00
JACK JEFF PRODUCT(1) 24716,00
STUART MICHAEL PRODUCT(1) 0,00
MIKE ANDERSON PRODUCT(2) 19388,00
JOHN ANGELA PRODUCT(2) 0,00
JACK JEFF PRODUCT(2) 0,00
STUART MICHAEL PRODUCT(2) 23338,00
MIKE ANDERSON PRODUCT(3) 0,00
JOHN ANGELA PRODUCT(3) 73088,00
JACK JEFF PRODUCT(3) 2995,00
STUART MICHAEL PRODUCT(3) 42656,00
MIKE ANDERSON PRODUCT(4) 2723,00
JOHN ANGELA PRODUCT(4) 0,00
JACK JEFF PRODUCT(4) 0,00
STUART MICHAEL PRODUCT(4) 0,00
MIKE ANDERSON PRODUCT(5) 217,00
JOHN ANGELA PRODUCT(5) 0,00
JACK JEFF PRODUCT(5) 0,00
STUART MICHAEL PRODUCT(5) 0,00
MIKE ANDERSON ... ...
JOHN ANGELA ... ...
JACK JEFF ... ...
STUART MICHAEL ... ...
MIKE ANDERSON PRODUCT(N) 6581,00
JOHN ANGELA PRODUCT(N) 0,00
JACK JEFF PRODUCT(N) 0,00
STUART MICHAEL PRODUCT(N) 0,00
到目前为止,我尝试的是将 Table1 批量插入到临时表中,然后处理这些数据,直到得到我想要的。问题是 PRODUCT() 列中的 N 是可变的,因此我无法创建具有固定列的临时表,并且我需要一个动态查询,以某种方式可以读取产品列的数量并使用它。
批量插入
BULK INSERT #temp
FROM '\\path\file.csv'
WITH
(
FIRSTROW = 1,
FIELDTERMINATOR= ';',
ROWTERMINATOR = '\n',
CODEPAGE='RAW'
);
临时表:
CREATE TABLE #temp(
col1 varchar(100) null,
col2 varchar(100) null,
col3 varchar(100) null,
col4 varchar(100) null,
col5 varchar(100) null,
...
col397 varchar(100) null,
col398 varchar(100) null,
col399 varchar(100) null,
col400 varchar(100) null
)
当我运行 BULK INSERT 时,出现此错误:
Msg 4832, Level 16, State 1, Line 1
Bulk load: An unexpected end of file was encountered in the data file.
Msg 7399, Level 16, State 1, Line 1
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7330, Level 16, State 2, Line 1
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".
发生这种情况是因为我创建了一个包含固定 400 列的临时表,其中有 127 个产品列。
我正在努力避免这样的事情:
DECLARE @NUM_ROWS INT
SET @NUM_ROWS = 123
IF @NUM_ROWS = 1
BEGIN
CREATE TABLE #temp(
col1 varchar(100) null
)
END
IF @NUM_ROWS = 2
BEGIN
CREATE TABLE #temp(
col1 varchar(100) null,
col2 varchar(100) null,
)
END
...
IF @NUM_ROWS = 400
BEGIN
CREATE TABLE #temp(
col1 varchar(100) null,
col2 varchar(100) null,
...
col4 varchar(100) null,
)
END
BULK INSERT #temp
FROM '\\path\file.csv'
WITH
(
FIRSTROW = 1,
FIELDTERMINATOR= ';',
ROWTERMINATOR = '\n',
CODEPAGE='RAW'
);
@NUM_ROWS 是我要创建临时表的列数。
有谁知道我可以将此 .csv 文件动态导入 SQL Server 的方法吗?我所说的动态是指创建一个临时表,其中包含我要批量插入的产品列数。或者避免我上面发布的错误的解决方法。
最佳答案
这是一种手动方法:
- 使用 Excel 打开 .csv 文件
- 向第一行添加 400 个列名称。当然,它们不必是字段的实际名称。只是占位符。这样,当您重新保存该文件时,该文件将具有 400 列。 (我将此称为手动方法,但您可以使用 VBA 脚本自动执行此操作)
从这里开始,都是 SQL:
- 使用标准批量插入,将其导入到包含 400 列的临时表中。
- 使用以下方法将数据插入到 table2 中:
Insert into Table2 Select CEO, Salesmen, 1 as ProductNum, [Product(1)] from Table1 where [Product(1)] is not null union Select CEO, Salesmen, 2 as ProductNum, [Product(2)] from Table1 where [Product(2)] is not null ... union Select CEO, Salesmen, 400 as ProductNum, [Product(400)] from Table1 where [Product(400)] is not null
当然,400 行会很难看,但您可以轻松阅读并从 1 数到 400。
关于sql-server - 将水平数据转换为垂直数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12942687/