将整数字段转换为时间戳...然后转换为日期

问题描述 投票:1回答:1

背景

我需要编写一个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文件的查询?例如,它最终应该:

  • 2016-08-12.csv
  • 2016-09-12.csv
  • 2016-03-12.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的字段的一部分,它被定义为“没有时区的时间戳|现在默认()”但是你可以看到当时间部分开始时该行被截断。你能解释一下为什么会这样吗?

postgresql
1个回答
1
投票

您可以通过将时间值转换为日期来创建文件名,如果您指的是具有当前内容的当前月份,则可以使用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
© www.soinside.com 2019 - 2024. All rights reserved.