【问题标题】:Mysql - Import a csv file with multiple fields into a single field using LOAD DATA LOCAL INFILEMysql - 使用 LOAD DATA LOCAL INFILE 将具有多个字段的 csv 文件导入单个字段
【发布时间】:2021-08-29 08:04:09
【问题描述】:

我有一个格式如下的 csv 文件:

phone1,phone2,phone3
11111111,22222222,333333333

我在 mysql 数据库中有一个名为“phone”的表,其中包含一个名为 phone 的字段。

如何将 csv 文件中的所有三列导入phone 字段?基本上:

select * from phone;

应该返回:

phone
11111111
22222222
33333333

如果我不能使用LOAD DATA LOCAL INFILE,在mysql中有没有其他方法可以做到这一点?

谢谢!

【问题讨论】:

  • 不幸的是,它没有。这似乎需要额外的步骤。我希望一步到位。我知道我可以创建一个临时表,在那里插入数据,然后将临时表中的数据插入“电话”表。
  • in can't see antither option and the solution is very flexible, you can switch to a stored procdure or do it in python or other laguages
  • 是的,我想过使用存储过程,但是当我尝试它时,我无法在 sp 中运行 LOAD DATA LOCAL INFILE,因为 mysql 不允许它。正如你所说,我可能不得不用其他语言来做这件事。谢谢!

标签: mysql sql csv import


【解决方案1】:

您可以先将数据导入中间表,然后将其拆分为行。

假设您将整个csv 行放在一个表中import

line
11111111,22222222,33333333

您可以通过使用换行符 (\n) 作为分隔符导入来做到这一点

LOAD DATA INFILE '/path/to/your/file.csv'
INTO TABLE import
FIELDS TERMINATED BY '\n'
LINES  TERMINATED BY '\n'
IGNORE 1 LINES

您现在可以使用substring_index 来拆分导入的 csv 行。为此,您需要知道的是条目数。您可以通过计算 csv 行的长度与删除所有逗号分隔符的自身长度的差异来轻松获得此数字。

从中创建一个数字序列,然后您可以将其与substring_index 一起使用以提取每个条目。

这可以做到,例如像这样:

insert into phone (num)
select
  SUBSTRING_INDEX(SUBSTRING_INDEX(import.line, ',', numbers.n), ',', -1) name
from
  (select 1 n union all
   select 2 union all select 3 union all
   select 4 union all select 5) numbers INNER JOIN import
  on CHAR_LENGTH(import.line)
     -CHAR_LENGTH(REPLACE(import.line, ',', ''))>=numbers.n-1
order by
  n

您可以使用recursive CTE 实现相同的目标

insert into phone (num)
with recursive
    N as ( select 1 as n union select n + 1 from N inner join import
        on n <= length(import.line) - length(replace(import.line, ',', '')))
    select distinct substring_index(substring_index(import.line, ',', n), ',', -1)
num from N inner join import

另一个有趣的方法是使用json_table。为此,您首先需要将 csv 行转换为 json_array

insert into phone
select j.line
from import i
join json_table(
  replace(json_array(i.line), ',', '","'),
  '$[*]' columns (line varchar(50) path '$')
) j

所有这些都会产生你想要的结果

select * from phone
number
11111111
22222222
33333333

另见this db<>fiddle

解决方案根据this SO questionthis answer 的不同答案改编。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-14
    • 2023-02-14
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 2013-09-24
    相关资源
    最近更新 更多