背景
我需要编写一个SQL查询,按日期对记录进行排序,然后按月将记录导出到csv文件。
例如,请考虑以下查询和结果:
select id, addy, abstime(start_ts) from wwdr where id > 3000;
输出:
1361571 | :10011@mydomain| 2016-08-12 17:59:36+00
1361578 | :19448@mydomain| 2016-08-12 17:59:16+00
1361579 | :10307@mydomain| 2016-08-12 18:00:07+00
1361581 | :10702@mydomain| 2016-08-12 17:54:41+00
1361582 | :12264@mydomain| 2016-08-12 18:00:13+00
1361588 | :10561@mydomain| 2016-09-12 18:00:20+00
1361589 | :10126@mydomain| 2016-09-12 18:00:13+00
1361593 | :25743@mydomain| 2016-09-12 17:54:03+00
1361597 | :13150@mydomain| 2016-03-12 17:58:10+00
1361600 | :14513@mydomain| 2016-03-12 18:00:36+00
1361602 | :46003@mydomain| 2016-03-12 18:00:31+00
1361603 | :11534@mydomain| 2016-03-12 18:01:11+00
1361608 | :58064@mydomain| 2016-01-12 18:00:45+00
1361614 | :14516@mydomain| 2016-02-12 18:00:16+00
1361620 | :14505@mydomain| 2016-08-12 17:57:13+00
1361621 | :13844@mydomain| 2016-08-12 17:50:44+00
1361623 | :333@mydomain | 2016-08-12 18:02:29+00
1361625 | :58066@mydomain| 2016-08-12 18:02:23+00
1361532 | :222@mydomain | 2016-08-12 17:58:24+00
1361541 | :30172@mydomain| 2016-08-12 17:57:56+00
1361542 | :10011@mydomain| 2018-02-12 17:56:37+00
1361545 | :333@mydomain | 2018-02-12 17:58:55+00
如何编写将为每个月创建单独CSV文件的查询?例如,它最终应该:
对于上面的例子。
另一个转折点是当前的东西,我需要它在一个名为current.csv
的文件中。
它不一定都在PLSQL中。我正在写一个bash脚本来包装这个逻辑。但我只需要一些关于从哪里开始查询的想法。
谢谢。
编辑1:
在添加到脚本之前,我正在尝试在命令行上运行,以了解提议的答案究竟在做什么。 所以这是我运行的命令:
lab-1:/etc/# for x in $(psql -U testuser testdb -h db-lab-2.mydomain.net -t -A -c "SELECT *, CASE WHEN DATE_TRUNC('MONTH', ABSTIME(start_ts)) = DATE_TRUNC('MONTH', CURRENT_DATE) THEN 'current' ELSE DATE_TRUNC('MONTH', ABSTIME(start_ts))::DATE::TEXT END FROM widgets limit 10");
do
> echo "---$x --- is the result"
> done
这是我看到的输出:(只是一个片段)
---3879602|2017-06-14 --- is the result
---14:25:40.862729|Completed|local|in|0|10571|10563|1497464696|1497464740|44|846ef34f-df2ef574-8834f0af|22|123||2017-06-01 --- is the result
---3879604|2017-06-14 --- is the result
---14:25:49.770659|Completed|local|in|0|3093685567|10096|1497464737|1497464749|12|a560b92b-cbd1-1235-5fb3-003018a67b79|asd|fasdf||2017-06-01 --- is the result
你看到的第一行包含两个字段,id 3879602和另一个名为im_date的字段的一部分,它被定义为“没有时区的时间戳|现在默认()”但是你可以看到当时间部分开始时该行被截断。你能解释一下为什么会这样吗?
您可以通过将时间值转换为日期来创建文件名,如果您指的是具有当前内容的当前月份,则可以使用CASE
表达式:
SELECT
CASE WHEN
DATE_TRUNC('MONTH', ABSTIME(start_ts)) = DATE_TRUNC('MONTH', CURRENT_DATE)
THEN 'current'
ELSE
DATE_TRUNC('MONTH', ABSTIME(start_ts))::DATE::TEXT
END,
id, addy, ABSTIME(start_ts)
FROM wwdr WHERE id > 3000;
您可以在bash
中获取原始数据并使用sed
解析它们:
for l in $(psql -t -A -c "SELECT ...")
do
filename=$(echo $l | sed 's/^\([^|]*\)\|.*$/\1/')
echo $l | sed 's/^[^|]*\|//' >> "${filename}.csv"
done
附录:您的声明应确保文件名的日期是第一列,如:
SELECT
CASE WHEN
DATE_TRUNC('MONTH', ABSTIME(start_ts)) = DATE_TRUNC('MONTH', CURRENT_DATE)
THEN 'current'
ELSE
DATE_TRUNC('MONTH', ABSTIME(start_ts))::DATE::TEXT
END, *
FROM widgets LIMIT 10
要获得对文件名的更多控制,您可以使用TO_CHAR
:
SELECT
CASE WHEN
DATE_TRUNC('MONTH', ABSTIME(start_ts)) = DATE_TRUNC('MONTH', CURRENT_DATE)
THEN 'current'
ELSE
TO_CHAR(ABSTIME(start_ts), 'YYYY-MM-DD')
END, *
FROM widgets limit 10