0

我有一个表 task_details。我需要从这个表中选择它的每周日期。我已经使用ISO 年ISO 周从该表中提取每周日期,因为我想将其周数提取为 53,如果它是 2015 年 12 月,那么在 12 月 28 日、12 月 29 日、12 月 30 日、12 月 31 日和 1 月 1 日2016 年 1 月 16,2 日,因为此类日期不应分成两个不同的星期。
下面给出了我用于ISO 年ISO 周的查询。

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

几周以来它工作得很好,但后来我在一个日期得到了这个奇怪的结果,以便在表格中记录。
该表没有 2017 年的数据。此外,yr列显示 2016 年,这是所期望的,但是newdate列和week列给出了奇怪的结果。为什么会这样?我该如何解决 ?

这是它的 SQL 小提琴:http ://sqlfiddle.com/#!15/53abf/1

4

2 回答 2

2

你不应该在提取函数中混合week使用公历而不是特殊的 ISO 日历。yearyear

请参阅第 9.9.1 节和关于 week 的评论

to_number(to_char(newdate, 'IW'), '99')有效地extract(week from newdate)

更改yrextract(isoyear from newdate)解决的问题的列。

调整后的 SQL 小提琴

于 2016-02-13T06:30:43.663 回答
1

@gwaigh已经消除了您对公历年和 ISO 年的困惑。

date_trunc()但是,通过获取每周的第一天,您的查询会更简单、更快捷:

SELECT name, id
     , date_trunc('week', newdate)::date AS week_date
     , 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;

还简化了您的查询。

SQL小提琴。

无论哪种方式,如果您使用timestamptz年份、星期或日期,则取决于您当前的时区设置。(可能是不同的年份,具体取决于您现在所在的位置。)

于 2016-02-13T07:11:49.830 回答