sql-server - 将水平数据转换为垂直数据

标签 sql-server sql-server-2008 import-from-excel

我有水平表格(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 的方法吗?我所说的动态是指创建一个临时表,其中包含我要批量插入的产品列数。或者避免我上面发布的错误的解决方法。

最佳答案

这是一种手动方法:

  1. 使用 Excel 打开 .csv 文件
  2. 向第一行添加 400 个列名称。当然,它们不必是字段的实际名称。只是占位符。这样,当您重新保存该文件时,该文件将具有 400 列。 (我将此称为手动方法,但您可以使用 VBA 脚本自动执行此操作)

从这里开始,都是 SQL:

  1. 使用标准批量插入,将其导入到包含 400 列的临时表中。
  2. 使用以下方法将数据插入到 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/

相关文章:

sql - 如何使用特定值更新 varbinary 字段?

sql - 一行中的多个记录

mysql - 将数据从 excel 文件写入数据库 (mysql) 时出现编码错误

mysql - Symfony3 : How to do a massive import from a CSV file as fast as possible?

c# - 如何解决 SqlException 在锁定时死锁 |通信缓冲资源

sql-server - 具有联接和动态列的 SQL SERVER PIVOT 表

python - 无法从 Linux 机器通过 python 连接 SQL 服务器

mysql - 将 MySQL 简单查询转换为 SQL Server

sql - 如何让 SQL Server XQUERY 返回 "There is no element named [Element]"以外的内容

R - 导入和合并多个 Excel 文件并添加文件源变量