Дата преобразования PostgreSQL (ГГГГ-WW) в сравнении с MySQL ('% x-% v')

0

Я пытаюсь преобразовать запрос из MySQL в PostgreSQL. Результаты немного меняются, поскольку, как представляется, существует разница между тем, как два языка определяют неделю вне года и в какие дни они включают.

Такая же логика дает разные результаты:

Синтаксис PostgreSQL -

select date from sales where to_char(date, 'YYYY-WW') >= '2017-51' AND to_char(date, 'YYYY-WW') <= '2017-52'

Синтаксис MySQL -

select date from sales where 
    DATE_FORMAT(date, '%x-%v') >='2017-51' and DATE_FORMAT(date, '%x-%v') <='2017-52'

Когда я запрашиваю PostgeSQL, результаты 2017-12-17: 2017-12-24. Результаты MySQL - 2017-12-18: 2017-12-25.

Почему здесь разница?

  • 0
    Вы сравниваете строки, а не даты, очень неэффективно. Принудительно преобразовывая каждое значение даты в строку перед сравнением, вы заставляете сервер выполнить полное сканирование таблицы, игнорируя все индексы. Если вы переписаете запрос так, чтобы параметры были действительными датами , вы получите на несколько порядков лучшую производительность
  • 2
    Вместо того, чтобы пытаться преобразовать даты в строки, найдите правильный способ для каждой базы данных вычислить дату на основе номера года и недели, например, to_date('201751', 'iyyyiw') для Postgres, STR_TO_DATE('201751', '%X%V') для MySQL, например: select date from sales where date between to_date('201751', 'iyyyiw') and to_date('201752', 'iyyyiw')
Показать ещё 2 комментария
Теги:
date-conversion

1 ответ

1

https://www.postgresql.org/docs/10/static/functions-formatting.html

WW неделя год (1-53) (первая неделя начинается в первый день года)

https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html

% v Неделя (01..53), где понедельник - первый день недели

поэтому ожидается такое поведение, потому что для postgres

t=# select to_char('2017-12-17'::date,'Day'), to_char('2017-12-17'::date,'WW');
  to_char  | to_char
-----------+---------
 Sunday    | 51
(1 row)

так как:

t=# select to_char('2017-01-01'::date,'Day'), to_char('2017-01-01'::date,'WW');
  to_char  | to_char
-----------+---------
 Sunday    | 01
(1 row)

а для MySQL:

select DATE_FORMAT('2017-01-01', '%x-%v');

является

2016-52

и таким образом 2017-12-17 - неделя 50

Ещё вопросы

Сообщество Overcoder
Наверх
Меню