我有一个将结果导出到文本文件的查询。代码如下:
Copy (
Select
foo.gid As addr_ID,
bar.geom As streets,
St_LineInterpolatePoint
(ST_LineMerge(bar.geom),
St_LineLocatePoint
(St_LineMerge(bar.geom),foo.geom)
) As interpolated_point
FROM foo
Left JOIN bar ON ST_DWithin(foo.geom, bar.geom, 50)
ORDER BY
foo.gid, St_Distance(foo.geom, bar.geom)
)
To '~path/my_file.txt' WITH DELIMITER ',';
表' foo'包含87行和' bar'包含16,060行。表' foo'还包含两列' start_time'和' end_time'描绘这样的不同年份的间隔:
Start_time End_time
2003-06-07 00:00:00 2004-09-30 23:59:59
2004-02-03 00:00:00 2005-03-10 23:59:59
2003-07-09 00:00:00 2012-05-06 23:59:59
我想导出我的选择查询结果,以便它每年生成TEXT文件,如下所示:
预期输出:
results_2003.txt
results_2004.txt
results_2005.txt
and so on...
有人可以建议我怎么做吗?我在Windows 7 Enterprise(x64)上使用PostgreSQL版本9.5(x64)。
编辑(1):
每年需要导出文本文件,例如:In' start_time'和' end_time'列,如果下限是2003,上限是2012,那么每年的文件需要导出,如预期输出所示。
编辑(2):
到目前为止,我一直在尝试开发完整的工作代码(非常感谢@Phillip代码和建议的链接)但是我遇到了问题,因为我反复遇到语法错误。该错误表示"语法错误在" 1" (Where子句)。下面我发布了代码(再次CREDIT转到Phillip):
-- In the below code: Addr, streets, agfisotime (start time in data type timestamp) and agtisotime (end time in data type timestamp) are original columns
DO $$
DECLARE
start_year date;
end_year date;
current_year date;
file_name text;
BEGIN
select date_trunc('year', min(agfisotime)), date_trunc('year', max(agtisotime))
into start_year, end_year
from Addr;
FOR current_year IN
SELECT * FROM generate_series(start_year, end_year, interval '1 year')
LOOP
Execute format('
Copy(
Select
Addr.gid As addr_ID,
streets.geom As streets,
St_LineInterpolatePoint(ST_LineMerge(streets.geom),
St_LineLocatePoint(St_LineMerge(streets.geom),Addr.geom))
As interpolated_point
FROM Addr
Left JOIN streets ON ST_DWithin(Addr.geom, streets.geom, 50)
WHERE agfisotime < current_year + interval '1 year'
AND agtisotime >= current_year
ORDER BY
Addr.gid, St_Distance(Addr.geom, streets.geom)
) TO ''C:/temp/out.csv'';
',current_year);
END LOOP;
RETURN;
END
$$
答案 0 :(得分:2)
这很复杂但有可能。基本问题是您需要为要写入的每个文件触发COPY
命令一次,并且需要使用动态SQL执行此操作。这里有一个解释:Use function variable in dynamic COPY statement
要实际多次触发COPY
命令,您需要使用匿名代码块或函数来检索年份列表,然后通过每年触发COPY
命令导出。
我已经测试了以下内容,它显示了基本原则,尽管它没有导出正确的数据:
DO $$
DECLARE
start_year date;
end_year date;
current_year date;
file_name text;
BEGIN
select date_trunc('year', min(start_time)), date_trunc('year', max(end_time))
into start_year, end_year
from foo;
FOR current_year IN
SELECT * FROM generate_series(start_year, end_year, interval '1 year')
LOOP
file_name := '/tmp/myFile_' || extract(year from current_year) || '.csv';
--- do your export here using current_year to filter the results
EXECUTE format('
COPY (
select start_time, end_time from foo
WHERE start_time < %L::date + interval ''1 year''
AND end_time >= %L::date
)
TO %L WITH DELIMITER '','';
',
current_year, current_year, file_name);
END LOOP;
END
$$;
每年您都需要过滤结果。所以你的查询看起来像这样(未经测试):
EXECUTE format('
COPY (
Select
foo.gid As addr_ID,
bar.geom As streets,
St_LineInterpolatePoint
(ST_LineMerge(bar.geom),
St_LineLocatePoint
(St_LineMerge(bar.geom),foo.geom)
) As interpolated_point
FROM foo
Left JOIN bar ON ST_DWithin(foo.geom, bar.geom, 50)
WHERE start_time < %L::date + interval ''1 year''
AND end_time >= %L::date
ORDER BY
foo.gid, St_Distance(foo.geom, bar.geom)
)
TO %L WITH DELIMITER '','';
',
current_year, current_year, file_name);