Получение правильного номера недели года

Я хочу получить правильный номер недели.

Используя функцию to_char, функция перечисляет неделю, начинающуюся с понедельника, но я хочу получить номер недели, учитывая, что неделя начинается в субботу.

Вот пример:

SELECT to_char('05-01-2013'::date,'daydd-mm-yyyy') as date_char, to_char('05-01-2013'::date,'IW') as week_number

Результат:

"saturday 05-01-2013";"01"   

А должно быть:

"saturday 05-01-2013";"02"  

Есть ли способ получить его?

Информация о конфигурации: Postgresql 9.2 под Windows 7


person Houari    schedule 11.02.2013    source источник
comment
Я не понимаю вашего вопроса. Выбор, который вы даете, не соответствует результату, который вы даете. 'SELECT to_char('01-05-2013'::date,'daydd-mm-yyyy') как date_char, to_char('01-05-2013'::date,'IW') как week_number;' даст вам: «среда01-05-2013»; «18». Какой результат вы хотите, чтобы он вам дал?   -  person David S    schedule 11.02.2013
comment
Почему в среду? 01.05.2013 была суббота! Я ищу сообщение для postgresql, что неделя начинается с субботы по пятницу, а не с понедельника по воскресенье.   -  person Houari    schedule 11.02.2013
comment
1 мая 2013 года будет среда. Если я вырезаю/вставляю ваш запрос, я получаю опубликованные результаты. Я думаю, что здесь может быть проблема с локалью. Я думаю, вам следует уточнить, какую локаль вы используете и что именно вы получаете и чего ожидаете.   -  person David S    schedule 11.02.2013
comment
Хорошо, 01.05.2013 имеет формат дд-мм-год; то есть: 1 января 2013 г.   -  person Houari    schedule 11.02.2013
comment
извините, то есть: 5 января 2013 г.   -  person Houari    schedule 11.02.2013
comment
Возможно, вы могли бы адаптировать ответ mysql к: Неделя года для недель, начинающихся с субботы   -  person Daniel Vérité    schedule 12.02.2013


Ответы (3)


Это даст правильный результат:

with first_friday as (
    select extract(doy from min(a)::date) ff
    from generate_series('2013-01-01'::date, '2013-01-07', '1 day') s(a)
    where extract(dow from a) = 5
)
select
    to_char(a, 'day'),
    a::date "day",
    floor((extract(doy from a) - (select ff from first_friday) - 1) / 7) + 2 week_number
from generate_series('2013-01-01'::date, '2013-01-31', '1 day') s(a)
;
  to_char  |    day     | week_number 
-----------+------------+-------------
 tuesday   | 2013-01-01 |           1
 wednesday | 2013-01-02 |           1
 thursday  | 2013-01-03 |           1
 friday    | 2013-01-04 |           1
 saturday  | 2013-01-05 |           2
 sunday    | 2013-01-06 |           2
 monday    | 2013-01-07 |           2
 tuesday   | 2013-01-08 |           2
 wednesday | 2013-01-09 |           2
 thursday  | 2013-01-10 |           2
 friday    | 2013-01-11 |           2
 saturday  | 2013-01-12 |           3
 sunday    | 2013-01-13 |           3
 monday    | 2013-01-14 |           3
 tuesday   | 2013-01-15 |           3
 wednesday | 2013-01-16 |           3
 thursday  | 2013-01-17 |           3
 friday    | 2013-01-18 |           3
 saturday  | 2013-01-19 |           4
 sunday    | 2013-01-20 |           4
 monday    | 2013-01-21 |           4
 tuesday   | 2013-01-22 |           4
 wednesday | 2013-01-23 |           4
 thursday  | 2013-01-24 |           4
 friday    | 2013-01-25 |           4
 saturday  | 2013-01-26 |           5
 sunday    | 2013-01-27 |           5
 monday    | 2013-01-28 |           5
 tuesday   | 2013-01-29 |           5
 wednesday | 2013-01-30 |           5
 thursday  | 2013-01-31 |           5
person Clodoaldo Neto    schedule 13.02.2013
comment
Нет, не все так просто, ведь с 29-12-2012 по 31-12-2012 должно быть 53, а не 01. - person Houari; 13.02.2013
comment
@Houari Вы имеете в виду, что первый день года всегда должен приходиться на первую неделю? Знаете ли вы об определении ISO, согласно которому первая неделя должна включать 4 января, и из-за этого иногда первый день приходится на 53-ю неделю? Вы должны четко указать, каково ваше определение неделя-год. - person Clodoaldo Neto; 13.02.2013
comment
Да, первый день года всегда должен быть на неделе номер 1. - person Houari; 13.02.2013
comment
Первая неделя начинается в первый день года, а первая пятница нового года приходится на неделю 1. - person Houari; 13.02.2013
comment
Да! это именно то, что я хочу, но только на 2013 год, это возможно на все даты? - person Houari; 13.02.2013
comment
@Houari Да, проверьте ответ на вопрос о функции. - person Clodoaldo Neto; 13.02.2013

SELECT EXTRACT(WEEK FROM now()); даст число 7, указывающее, что (в настоящее время) мы находимся на 7-й неделе года. Недели Postgres по умолчанию начинаются в понедельник.

SELECT EXTRACT(WEEK FROM timestamp '2013-01-05'); даст 1, так как с начала года прошло всего 5 дней.

Изменить кажется, что он начинает отсчитывать недели только с момента, когда прошла первая полная неделя. Не написав свою собственную функцию, я бы предложил использовать это или использовать другой метод, чтобы найти ее.

person Lucas    schedule 11.02.2013
comment
Да, мне было интересно, что функция должна быть не готова к использованию или что-то нужно настроить. черт возьми - person Houari; 11.02.2013

Вам придется использовать extract(doy from ...) и extract(dow from ...) плюс немного математики. Подробности в документации.

person Community    schedule 11.02.2013
comment
Я ищу не день недели, а номер недели года - person Houari; 11.02.2013
comment
И номер недели должен учитывать, что неделя начинается с субботы по пятницу. - person Houari; 11.02.2013
comment
Должен ли я написать функцию для достижения этого? - person Houari; 11.02.2013
comment
Ты мог бы. Это была бы довольно простая функция SQL и упростила бы дальнейшие запросы. А точнее - сделать его более читабельным. - person ; 12.02.2013