SQL 查询多个 CSV 文件的好方法?

SQL 查询多个 CSV 文件的好方法?

我一直在寻找一种将 CSV 文件作为关系数据库表进行遍历的方法。

我做了一些研究,因为我发现没有任何东西完全符合我的要求。我发现了几个部分不错的选择,即:

  1. 术语SQL- 它接受 stdin 或一个文件并允许在其上执行一些 sql - 但只设置一个“表”
  2. csv2sqlite- 这是非常有前途的,因为它允许比 termsql 潜在更多的 sql 优点 - 但仍然只有一个“表”
  3. 这个 ULSE 问题- 描述了如何使用 unix 文件遍历命令实现集合操作 - 有希望和可能的起点

遍历并执行一些类似数据库的操作是可能的,而且非常简单单身的csv/文本文件(列总和、平均值、最小值、最大值、子集等),但不是两个文件,它们之间有一些联系。还可以将文件导入到临时数据库中进行查询,我已经这样做了,尽管没有我想要的那么实用。

长话短说- 我基本上想要一种方便的方法来对 csv 文件进行快速而肮脏的 sql 连接。不是在寻找成熟的基于文本的 RDBMS,而只是寻找一种更好的方法来对 csv RDBMS 提取进行一些分析。

例子:

sqlthingy -i tbl1.csv tbl2.csv -o 'select 1,2,3 from tbl1, tbl2 where tbl1.1 = tbl2.1'

这似乎是一个足够有趣的问题,我可以花一些时间来解决,但我想知道它是否已经存在。

答案1

看一眼数据库表(Perl),或csvkit(Python)。它们都有各种问题和局限性,但它们通常适用于“小”数据。当然,当它们不够时,您始终可以回退到适当的数据库。

答案2

你想要的是join命令,这是由 POSIX 指定

这是您的示例伪代码命令:

sqlthingy -i tbl1.csv tbl2.csv -o 'select 1,2,3 from tbl1, tbl2 where tbl1.1 = tbl2.1'

这是一个实际工作命令,使用join等效命令:

join -t, tbl1.csv tbl2.csv

如果两个文件都只有两个字段(以逗号分隔),则此join命令正是您在伪代码中表示的内容。

如果它们有更多字段,但您只想每个文件中的第二个字段,仍然加入第一个字段,您可以使用:

join -t, -o 0,1.2,2.2 tbl1.csv tbl2.csv

如果您想加入不同的领域,也有相应的标志。

它不是一个成熟的 RDBMS;而是一个成熟的 RDBMS。例如,您只能使用两个文件和一个连接字段。但对于你所要求的:

TL;DR - 我基本上想要一种方便的方法来对 csv 文件进行快速而肮脏的 sql 连接。不是在寻找成熟的基于文本的 RDBMS,而只是寻找一种更好的方法来对 csv RDBMS 提取进行一些分析。

它符合要求完美


您还应该检查一下comm也由 POSIX 指定,用于打印两个文件共有的行(或仅存在于其中一个或另一个文件中,或类似的东西)。

另请注意,join和都可以通过用作文件名来comm对标准输入进行操作。-


如果您想要带有“group by”子句的 SQL“count()”命令的等效项,只需获取所需的列(它将join使用连接字段进行排序,或者如果直接来自文件,您可以自己排序)并通过管道将其通过uniq -c


之间awk,加入,独特的,通讯, 和种类,您可以使用 CSV 做一些非常奇特的事情。所有这些都符合 POSIX 标准。

答案3

阿帕奇钻机可以直接查询 CSV 和 JSON 文件,并连接它们。

您只需第一次定义文件位置并根据文件扩展名调整设置(例如是否使用第一行作为标题)。

那么就好像您使用的是mysql客户端,但表是磁盘上的实际文件

$ ./bin/drill-embedded 
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=512M; support was removed in 8.0
Nov 07, 2017 7:05:52 PM org.glassfish.jersey.server.ApplicationHandler initialize
INFO: Initiating Jersey application, version Jersey: 2.8 2014-04-29 01:25:26...
apache drill 1.11.0 
"drill baby drill"
0: jdbc:drill:zk=local> SELECT ix.field1, o.field2, o.field3 
. . . . . . . . . . . > FROM dfs.myfolder.`file1.tsv` ix
. . . . . . . . . . . > LEFT JOIN dfs.myfolder.`file2.tsv` o ON (o.field=ix.field)
. . . . . . . . . . . > LIMIT 10;
+-------------+-------------+---------------+
| field1      | field2      | field3        |
+-------------+-------------+---------------+
...redacted...
+-------------+-------------+---------------+
10 rows selected (0.656 seconds)
0: jdbc:drill:zk=local> 

相关内容