我可以使用 SQL 将存储为 CSV(逗号分隔值)的表列的内容拆分为新表中的各个行吗?

2024-01-01

我看到有几个相关的问题和答案,但不完全是我需要的,所以我会问一个新问题。我有一个包含数千行商店库存数据的 CSV 文件,我想将其导入 MS SQL Server 数据库并使用 SQL 来处理它们。导入 CSV 文件后,SQL 表将具有包含 CSV 数据的三列。问题是我需要将此 CSV 数据放入单独的行中以便进行更多分析。我希望最终得到两个表:通过导入 CSV 文件创建的原始表和通过拆分 CSV 创建的表。下面是这两个表的样子:

/Table1 (the original CSV file).  First row is column names:
StoreID,Date,StoreName,City,State,Category1CSV,Category2CSV,Category3CSV
1051,2/16/2014,Easton,Columbus,OH,"Flour,Yeast,Baking Powder","Milk,Water,Oil","Cinnamon,Sugar"
1425,1/14/2014,Crocker Park,Westlake,OH,"Baking Powder,Yeast,Flour","Oil,Milk,Water","Rosemay,Cinnamon,Sugar"
/Table2 (after splitting the CSV column contents). First row is column names:
StoreID,Date,StoreName,City,State,ItemName,ItemRank,ItemCategory
1051,2/16/2014,Easton,Columbus,OH,Flour,1,1
1051,2/16/2014,Easton,Columbus,OH,Yeast,2,1
1051,2/16/2014,Easton,Columbus,OH,Baking Powder,3,1
1051,2/16/2014,Easton,Columbus,OH,Milk,4,2
1051,2/16/2014,Easton,Columbus,OH,Water,5,2
1051,2/16/2014,Easton,Columbus,OH,Oil,6,2
1051,2/16/2014,Easton,Columbus,OH,Cinnamon,7,3
1051,2/16/2014,Easton,Columbus,OH,Sugar,8,3
1425,1/14/2014,Crocker Park,Westlake,OH,Baking Powder,1,1
1425,1/14/2014,Crocker Park,Westlake,OH,Yeast,2,1
1425,1/14/2014,Crocker Park,Westlake,OH,Flour,3,1
1425,1/14/2014,Crocker Park,Westlake,OH,Oil,4,2
1425,1/14/2014,Crocker Park,Westlake,OH,Milk,5,2
1425,1/14/2014,Crocker Park,Westlake,OH,Water,6,2
1425,1/14/2014,Crocker Park,Westlake,OH,Rosemary,7,3
1425,1/14/2014,Crocker Park,Westlake,OH,Cinnamon,8,3
1425,1/14/2014,Crocker Park,Westlake,OH,Sugar,9,3

SQL 列数据类型有:

Table 1
StoreID - int
Date - date
StoreName - nvarchar(50)
City- nvarchar(50)
State- nvarchar(50)
Category1CSV - nvarchar(MAX)
Category2CSV - nvarchar(MAX)
Category3CSV - nvarchar(MAX)

Table2
StoreID - int
Date - date
StoreName - nvarchar(50)
City- nvarchar(50)
State - nvarchar(50)
ItemName - nvarchar(50)
ItemRank - tinyint
ItemCategory -tinyint

表 1 中标记为 Category1CSV、Category2CSV 和 Category3CSV 内容的列映射到表 2 列:ItemName、ItemRank、ItemCategory,其中 ItemName 是项目(例如:面粉),ItemRank 是项目在 CSV 列表中的顺序,ItemCategory 是1,2 或 3,具体取决于数据是来自 Category1CSV、Category2CSV 还是 Category3CSV。

最重要的方面(除了拆分 CSV 列之外)是维护 CSV 列中项目的顺序。例如,StroreID 1051 的 Category1CSV 内容为“面粉、酵母、发酵粉”。这些将映射到 ItemName、ItemRank 和 ItemCategory 列,使得 ItemName = Flour,它的 ItemRank = 1,并且 ItemCategory = 1。这将是表 2 中的第一行。第二行将是 ItemName = Yeast,它的 ItemRank = 2,ItemCategory = 1,依此类推,直到最终得到如上表 2 所示的内容。此外,您还会注意到 ItemRank 编号从 Category1CSV 列的内容开始,然后继续到 Category2CSV,最后是 Category3CSV。

经过冗长的解释后,是否有可能有一些 SQL 语句为我从表 1 创建表 2?如果是这样,那会是什么样子?我计划使用 MS SQL Server Express 2012。

或者...正如有人向我建议的那样,最好在 Excel 或 Python 脚本中使用一些 VBA(也许与 Notepad++ 结合使用?)来完成此操作,然后导入最终数据?不管怎样,我都不在乎,我只是不能继续手动编辑 CSV 文件,因为它非常乏味且耗时。


我将使用 Split 函数来分割附加值。

我使用的 Split 函数使用数字(包含数字 1 到 1,000,000 的表格)来促进拆分过程。

一旦 Numbers 表和 Split 函数就位,我将使用 CROSS APPLY 函数将 Split 应用于 CSV 列。分割 CSV 列的代码如下所示(这只是基于您提供的数据的几个测试行)。

DECLARE @Table TABLE (val1 VARCHAR(50), val2 VARCHAR(50), val3 VARCHAR(50), csv1 VARCHAR(100), csv2 VARCHAR(100), csv3 VARCHAR(100))
INSERT INTO @Table
VALUES ('Easton', 'Columbus', 'OH', 'Flour,Yeast,Baking Powder','Milk,Water,Oil','Cinnamon,Sugar')
 , ('Crocker Park', 'Westlake', 'OH', 'Baking Powder,Yeast,Flour','Oil,Milk,Water','Rosemary,Cinnamon,Sugar')

SELECT tbl.val1, val2, val3, apl.*
  FROM @Table tbl
 CROSS APPLY(
    SELECT val
      FROM dbo.Split(tbl.csv1, ',')
   ) apl

UNION ALL

SELECT tbl.val1, val2, val3, apl.*
  FROM @Table tbl
 CROSS APPLY(
    SELECT val
      FROM dbo.Split(tbl.csv2, ',')
   ) apl

UNION ALL

SELECT tbl.val1, val2, val3, apl.*
  FROM @Table tbl
 CROSS APPLY(
    SELECT val
      FROM dbo.Split(tbl.csv3, ',')
   ) apl
 ORDER BY val1

根据样本日期,其输出将如下所示。

Crocker Park    Westlake    OH  Baking Powder
Crocker Park    Westlake    OH  Cinnamon
Crocker Park    Westlake    OH  Flour
Crocker Park    Westlake    OH  Milk
Crocker Park    Westlake    OH  Oil
Crocker Park    Westlake    OH  Rosemary
Crocker Park    Westlake    OH  Sugar
Crocker Park    Westlake    OH  Water
Crocker Park    Westlake    OH  Yeast
Easton          Columbus    OH  Baking Powder
Easton          Columbus    OH  Cinnamon
Easton          Columbus    OH  Flour
Easton          Columbus    OH  Milk
Easton          Columbus    OH  Oil
Easton          Columbus    OH  Sugar
Easton          Columbus    OH  Water
Easton          Columbus    OH  Yeast

这是创建 Numbers 表的代码

DECLARE @tbl TABLE (n INT)
INSERT INTO @tbl (n)
VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)

; WITH Num AS(
SELECT one.n
  FROM @tbl one
 CROSS JOIN @tbl two
 CROSS JOIN @tbl three
 CROSS JOIN @tbl four
 CROSS JOIN @tbl five
 CROSS JOIN @tbl six
)
SELECT ROW_NUMBER() OVER(ORDER BY n) AS n
  INTO dbo.Numbers
  FROM Num

ALTER TABLE dbo.Numbers
ALTER COLUMN n INT NOT NULL

ALTER TABLE dbo.Numbers 
ADD PRIMARY KEY (n)
GO

最后,这是创建 Split 函数的代码。

CREATE FUNCTION dbo.Split
(
@List VARCHAR(MAX),
@Delimiter VARCHAR(255)
)
RETURNS TABLE
AS
RETURN
(
SELECT val = SUBSTRING(@List, n, CHARINDEX(@Delimiter, @List + @Delimiter, n) - n)
  FROM dbo.Numbers
 WHERE n <= CONVERT(INT, LEN(@List)) 
   AND SUBSTRING(@Delimiter + @List, n, LEN(@Delimiter)) = @Delimiter
 );
GO
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以使用 SQL 将存储为 CSV(逗号分隔值)的表列的内容拆分为新表中的各个行吗? 的相关文章

随机推荐

  • 在 PERL 中从 Windows 访问 Microsoft SQL Server

    我正在使用 SQL Server 驱动程序 但这是我得到的以下错误 DBI connect Driver SQL Server database host cartertest failed Microsoft ODBC Driver Ma
  • 如何使用另一个模块的反应式数据帧更新闪亮模块

    该模块的目标是创建一个根据数据选择器模块的输出而变化的反应性条形图 不幸的是 条形图没有更新 它停留在选定的第一个变量上 我尝试创建观察者函数来更新条形图 但无济于事 我还尝试将选择器服务器模块嵌套在 barplot 模块中 但出现错误 警
  • 装配性能调整

    我正在编写一个编译器 更多的是为了好玩 但我想尝试使其尽可能高效 例如 我被告知在英特尔架构上使用除EAX执行数学运算会产生成本 大概是因为它交换为EAX进行实际的数学计算 这里至少有一个来源说明了这种可能性 http www swanso
  • MediaTek 处理器上的双精度值计算错误

    我发现我在市场上发布的一款应用程序在某些手机上产生了奇怪的结果 经过调查发现 一个计算两个地理点之间距离的函数存在问题 有时它会返回完全错误的值 此问题仅在具有以下功能的设备上重现联发科MT6589 http www mediatek co
  • localstorage - 保存数组[重复]

    这个问题在这里已经有答案了 我有本地存储 可以保存输入并将它们推送到列表中 现在我想将列表保存在本地存储中 因为当我重新加载列表时 列表会重置var fav new Array 在此开头定义jsFiddle http jsfiddle ne
  • 如何在 java 中解组 ruby​​ 对象?

    我有一个对象 我想用java获取它的内容 唯一的问题是目前在 ruby 中 irb main 050 0 gt blah gt BAh7ByIeYXV0aGVudGljYXRpb25fc3RyYXRlZ2llczAiCXVzZXJpBg 2
  • AVAudioEngine 在 iOS14 中获取 inputNode 属性崩溃

    这是一个启动audioEngine的函数 void startAudioEngine NSError error nil if self audioEngine isRunning self audioEngine AVAudioEngin
  • Python 装饰器有哪些常见用途? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 虽然我喜欢将自己视为一名相当有能力的 Python 程序员 但我从未理解过的语言的一个方面是装饰器 我知道它们是什么 表面上 我读过 St
  • 如何使用 Sublime Text 3 配置 MinGW?

    我最近安装了 MinGW 并且一直试图让它与 Sublime Text 3 一起使用 以便在编译脚本时打开 cmd 但是没有任何效果 当我去工具 gt 构建系统 gt 新构建系统并保存此脚本 我不断收到错误 C 不被识别为内部或外部命令 可
  • C 中数组索引减去字符意味着什么?

    include
  • 将多个控件放入更新面板的正确方法是什么?

    我有一份注册表单 其中包含 3 到 4 个下拉控件和 2 个日期选择器 现在当选择下拉控件值时 触发 selectedindex 更改 那么我不希望我的页面回发 我已经使用更新面板来停止这种帖子行为 如下所示
  • Spray.io:何时(不)使用非阻塞路由处理?

    如果我们正在考虑生产级 REST API 我们是否应该尽可能使用非阻塞 例如 def insertDbAsync rows RowList Future Unit val route path database insertRowList
  • 在并发环境中处理 max(ID)

    我是 Web 应用程序编程和使用 SQL Server 等 RDBMS 处理并发的新手 我正在使用 SQL Server 2005 Express 版 我正在生成员工代码 其中最后四位数字来自此查询 SELECT max ID FROM e
  • Node.js - Mongoose - 检查集合是否存在

    我需要使用 mongoose 插入一些数据 但集合的名称是由用户在插入时提供的 所以我首先必须检查集合是否存在 我知道如何检查集合是否存在的方法是查询system namespaces收藏 我可以看到 3 种可能的方法来做到这一点 寻找查询
  • 实体框架代码首先创建“鉴别器”列

    我正在使用 EF CF 方法创建一个带有 MySQL 的网站 由于某种原因 EF 在我的 Post 表中创建了一个名为 Discriminator 的列 并包含 VARCHAR Post 为什么要创建这个专栏 我可以做些什么来避免它被创建吗
  • 提交按钮变灰

    我的表单上有一个非常重要的提交按钮 我不希望用户多次点击它 有没有办法让它不可点击或在点击后变灰 也许是点击事件 我的简单代码如下
  • 如何在 SQL 中对连续值进行分组

    我在 SQL Server 2014 中有一个表 其中的示例数据如下 WK NUM NET SPRD LCL 10 0 11 1500 12 3600 13 3800 14 4000 我正在尝试在工作中编写一个奖金结构 我需要在 WK NU
  • 如何在 IDLE 中删除多行制表符缩进?

    如果您想在 Python IDLE 中缩进多行 只需标记这些行并按 Tab 键即可 但是 如果您想删除多行中的缩进怎么办 Shift Tab 在 IDLE 中不起作用 如果您使用 IDLE 则可以使用Ctrl 缩进和Ctrl 取消缩进
  • 在 Perl 中,如何检查给定函数是从哪个模块导入的?

    我有一个调用该函数的代码 但我不知道这个函数属于哪个模块 我需要它来修改这个功能 我怎样才能检查它 The Devel Peek http search cpan org perldoc Devel Peek模块可以非常方便地获取有关变量的
  • 我可以使用 SQL 将存储为 CSV(逗号分隔值)的表列的内容拆分为新表中的各个行吗?

    我看到有几个相关的问题和答案 但不完全是我需要的 所以我会问一个新问题 我有一个包含数千行商店库存数据的 CSV 文件 我想将其导入 MS SQL Server 数据库并使用 SQL 来处理它们 导入 CSV 文件后 SQL 表将具有包含