在 Postgresql 中获取 ISO 日期的奇怪结果
Getting a weird result for ISO Date in Postgresql
我有一个tabletask_details。我需要从这个 table select 它的 每周日期 。我使用 ISO Year & ISO Week 从 table 中提取每周日期,因为我想将其周数提取为 53如果是 2015 年 12 月,那么在 2015 年 12 月 28 日、12 月 29 日、12 月 30 日、12 月 31 日和 16 年 1 月 1 日、2016 年 1 月 2 日,因为这些日期不应分为两个不同的星期。
下面给出了我用于 ISO Year & ISO Week 的查询。
select
name, id,
to_date(week || ' ' || yr, 'IW IYYY') week_date,
sum(worked_hours) worked_hours_per_week,
week, yr
from (
select
name, id,
newdate, hours worked_hours,
to_number(to_char(newdate, 'IW'), '99') week,
extract( year from newdate) yr
from task_details t
) sub
where worked_hours > 0
group by name, id, to_date(week || ' ' || yr, 'IW IYYY'), week, yr
order by yr, week
这几周工作正常,但后来我在 table.
中的一个记录日期得到了这个奇怪的结果 table 没有2017.Also 年的数据,yr 列显示的是 2016 年,这符合要求,但 newdate 列和 week 列给出了奇怪的结果。为什么会这样?我该如何解决这个问题?
这里是 SQL fiddle :http://sqlfiddle.com/#!15/53abf/1
您不应在提取函数中混合使用 week
和 year
,因为 year
适用于公历而不是特殊的 ISO 日历。
参见 section 9.9.1 and comments about week。
to_number(to_char(newdate, 'IW'), '99')
实际上是 extract(week from newdate)
将 yr
列更改为 extract(isoyear from newdate)
即可解决您的问题。
已经消除了您对公历和 ISO 年份的困惑。
但是,使用 date_trunc()
获取每周的第一天,您的查询会更简单、更快速:
SELECT name, id
, <b>date_trunc('week', newdate)::date AS week_date</b>
, extract(week FROM newdate)::int AS week
, extract(isoyear from newdate)::int AS isoyr -- must be ISO year to match
, sum(hours) AS worked_hours_per_week
FROM task_details
WHERE hours > 0
GROUP BY name, id, week_date, week, yr
ORDER BY week_date;
还简化了您的查询。
无论哪种方式,如果您使用 timestamptz
,那么年、周或日期取决于您当前的时区设置。 (可能是不同的年份,具体取决于您现在所在的位置。)
我有一个tabletask_details。我需要从这个 table select 它的 每周日期 。我使用 ISO Year & ISO Week 从 table 中提取每周日期,因为我想将其周数提取为 53如果是 2015 年 12 月,那么在 2015 年 12 月 28 日、12 月 29 日、12 月 30 日、12 月 31 日和 16 年 1 月 1 日、2016 年 1 月 2 日,因为这些日期不应分为两个不同的星期。
下面给出了我用于 ISO Year & ISO Week 的查询。
select
name, id,
to_date(week || ' ' || yr, 'IW IYYY') week_date,
sum(worked_hours) worked_hours_per_week,
week, yr
from (
select
name, id,
newdate, hours worked_hours,
to_number(to_char(newdate, 'IW'), '99') week,
extract( year from newdate) yr
from task_details t
) sub
where worked_hours > 0
group by name, id, to_date(week || ' ' || yr, 'IW IYYY'), week, yr
order by yr, week
这几周工作正常,但后来我在 table.
中的一个记录日期得到了这个奇怪的结果 table 没有2017.Also 年的数据,yr 列显示的是 2016 年,这符合要求,但 newdate 列和 week 列给出了奇怪的结果。为什么会这样?我该如何解决这个问题?
这里是 SQL fiddle :http://sqlfiddle.com/#!15/53abf/1
您不应在提取函数中混合使用 week
和 year
,因为 year
适用于公历而不是特殊的 ISO 日历。
参见 section 9.9.1 and comments about week。
to_number(to_char(newdate, 'IW'), '99')
实际上是 extract(week from newdate)
将 yr
列更改为 extract(isoyear from newdate)
即可解决您的问题。
但是,使用 date_trunc()
获取每周的第一天,您的查询会更简单、更快速:
SELECT name, id
, <b>date_trunc('week', newdate)::date AS week_date</b>
, extract(week FROM newdate)::int AS week
, extract(isoyear from newdate)::int AS isoyr -- must be ISO year to match
, sum(hours) AS worked_hours_per_week
FROM task_details
WHERE hours > 0
GROUP BY name, id, week_date, week, yr
ORDER BY week_date;
还简化了您的查询。
无论哪种方式,如果您使用 timestamptz
,那么年、周或日期取决于您当前的时区设置。 (可能是不同的年份,具体取决于您现在所在的位置。)