使用 COPY FROM 从 CSV 导入数据时转换列
Casting column when using COPY FROM to import data from CSV
使用 PostgreSQL 12,我尝试从 CSV 中导入数据,格式如下:
country,state,county,lat,lng,type,measure,beds,population,year,source,source_url
US,AK,ketchikan gateway,63.588753,-154.493062,ICU,1000HAB,3.928701,13745,2018,arcgis,https://services1.arcgis.com/Hp6G80Pky0om7QvQ/arcgis/rest/services/Hospitals_1/FeatureServer/0
US,AK,kodiak island,63.588753,-154.493062,ACUTE,1000HAB,,n,2018,arcgis,https://services1.arcgis.com/Hp6G80Pky0om7QvQ/arcgis/rest/services/Hospitals_1/FeatureServer/0
请注意,第二行的 "population" 字段有一个 n
而不是空的。我的目标是导入 CSV,以便 "population" 列为 BIGINT 并且 "n" 被替换为 NULL。我目前的解决方案是:
CREATE TABLE temp_table
(
country CHAR(2),
state CHAR(2),
county VARCHAR(255),
lat DOUBLE PRECISION,
lng DOUBLE PRECISION,
type VARCHAR(11),
measure VARCHAR(255),
beds DOUBLE PRECISION,
pop VARCHAR(255),
year SMALLINT,
source VARCHAR(255),
source_url VARCHAR(255)
);
COPY temp_table
FROM 'C:\Users\mconr\Downloads\global-hospital-beds-capacity-for-covid19\hospital_beds_USA_v1.CSV'
WITH (DELIMITER ',', FORMAT CSV, HEADER TRUE);
SELECT country, state, county, lat, lng, type, measure, beds, CAST (NULLIF (pop, 'n') AS BIGINT) AS population, year, source, source_url
INTO USA
FROM temp_table;
DROP TABLE temp_table;
我目前的解决方案是创建一个临时的 table,其中 "population" 是 VARCHAR(255),导入数据,从 SELECT 语句创建一个新的 table将 "n" 替换为 NULL 并将该列转换为 BIGINT,然后删除临时 table。但是,这似乎有点低效,因为我正在创建和删除中间 table。有谁知道更好的方法吗?
您可以将 NULL 参数设置为 'n',但这会破坏其他情况,其中 null 字段以通常的方式(通过未加引号的空字符串)表示,而不是 'n'. COPY 不允许您为每列设置 NULL。
你目前的方法对我来说似乎很好,这将是我的第一选择(除了修复这个文件的生成器,它可能不受你的控制)。您还可以使用 Perl 或 awk 或 sed 编写一些东西,将文件编辑为流以将 ',n,' 转换为 ',' 并使用 PROGRAM 功能将其连接到 COPY,但这似乎很繁琐且错误容易,我怀疑效率提升会那么大。
这被认为是过早的优化之一,是万恶之源。这真的是一个有意义的问题吗?
使用 PostgreSQL 12,我尝试从 CSV 中导入数据,格式如下:
country,state,county,lat,lng,type,measure,beds,population,year,source,source_url
US,AK,ketchikan gateway,63.588753,-154.493062,ICU,1000HAB,3.928701,13745,2018,arcgis,https://services1.arcgis.com/Hp6G80Pky0om7QvQ/arcgis/rest/services/Hospitals_1/FeatureServer/0
US,AK,kodiak island,63.588753,-154.493062,ACUTE,1000HAB,,n,2018,arcgis,https://services1.arcgis.com/Hp6G80Pky0om7QvQ/arcgis/rest/services/Hospitals_1/FeatureServer/0
请注意,第二行的 "population" 字段有一个 n
而不是空的。我的目标是导入 CSV,以便 "population" 列为 BIGINT 并且 "n" 被替换为 NULL。我目前的解决方案是:
CREATE TABLE temp_table
(
country CHAR(2),
state CHAR(2),
county VARCHAR(255),
lat DOUBLE PRECISION,
lng DOUBLE PRECISION,
type VARCHAR(11),
measure VARCHAR(255),
beds DOUBLE PRECISION,
pop VARCHAR(255),
year SMALLINT,
source VARCHAR(255),
source_url VARCHAR(255)
);
COPY temp_table
FROM 'C:\Users\mconr\Downloads\global-hospital-beds-capacity-for-covid19\hospital_beds_USA_v1.CSV'
WITH (DELIMITER ',', FORMAT CSV, HEADER TRUE);
SELECT country, state, county, lat, lng, type, measure, beds, CAST (NULLIF (pop, 'n') AS BIGINT) AS population, year, source, source_url
INTO USA
FROM temp_table;
DROP TABLE temp_table;
我目前的解决方案是创建一个临时的 table,其中 "population" 是 VARCHAR(255),导入数据,从 SELECT 语句创建一个新的 table将 "n" 替换为 NULL 并将该列转换为 BIGINT,然后删除临时 table。但是,这似乎有点低效,因为我正在创建和删除中间 table。有谁知道更好的方法吗?
您可以将 NULL 参数设置为 'n',但这会破坏其他情况,其中 null 字段以通常的方式(通过未加引号的空字符串)表示,而不是 'n'. COPY 不允许您为每列设置 NULL。
你目前的方法对我来说似乎很好,这将是我的第一选择(除了修复这个文件的生成器,它可能不受你的控制)。您还可以使用 Perl 或 awk 或 sed 编写一些东西,将文件编辑为流以将 ',n,' 转换为 ',' 并使用 PROGRAM 功能将其连接到 COPY,但这似乎很繁琐且错误容易,我怀疑效率提升会那么大。
这被认为是过早的优化之一,是万恶之源。这真的是一个有意义的问题吗?