Date_trunc PostgreSQL в MySQL - PullRequest
       3

Date_trunc PostgreSQL в MySQL

17 голосов
/ 04 апреля 2011

Недавно я познакомился с PostgreSQL (используя 8.2) и обнаружил, что функция date_trunc чрезвычайно полезна для простого сопоставления отметок времени между определенными днями / месяцами / и т. Д. Я полагаю, что реальная полезность функции заключается в том, что она сохраняет выходные данные в формате отметки времени.

Мне пришлось переключиться на mySQL (5.0) и найти, что некоторые функции даты довольно не сравниваются. Функция извлечения кажется полезной, и найденная мною функция date решает некоторые из моих проблем, но есть ли способ реплицировать PostgreSQL date_trunc?

Ниже приведен пример того, как я использовал date_trunc для сопоставления запрошенных временных отметок только с последними 4 месяцами, включая текущий месяц, но только если неделя уже прошла в этом месяце:

WHERE date_trunc('month', QUERY_DATE) BETWEEN 
    date_trunc('month', now()) - INTERVAL '4 MONTH' AND 
    date_trunc('month', now() - INTERVAL '1 WEEK')

Я понятия не имею, как воссоздать такое условие в mySQL. Итак, мой вопрос в конце дня: можно ли выполнить этот тип запроса в mySQL, пытаясь повторить date_trunc (и как), или мне нужно начать смотреть на эти типы запросов другим способом, чтобы заставить их работать в MySQL (и предложения о том, как это сделать)?

Ответы [ 2 ]

27 голосов
/ 05 апреля 2011

Функция извлечения кажется полезной, и функция даты, которую я нашел, решает некоторые из моих проблем, но есть ли способ реплицировать PostgreSQL date_trunc?

Действительно, EXTRACT похоже, что это будет самое близкое соответствие для этого конкретного случая.

Ваш исходный код в PG:

WHERE date_trunc('month', QUERY_DATE) BETWEEN 
    date_trunc('month', now()) - INTERVAL '4 MONTH' AND 
    date_trunc('month', now() - INTERVAL '1 WEEK')

Использование EXTRACT:

WHERE EXTRACT(YEAR_MONTH FROM QUERY_DATE)
      BETWEEN
          EXTRACT(YEAR_MONTH FROM NOW() - INTERVAL 4 MONTH)
      AND
          EXTRACT(YEAR_MONTH FROM NOW() - INTERVAL 1 WEEK)

Несмотря на то, что он должен быть функционально идентичен, фактически выполняется сопоставление дат в строку ГГГГМ перед выполнением сравнения.

Другой вариант - использовать DATE_FORMAT для перестройки строки датыи принудительно введите его в начале месяца:

WHERE DATE_FORMAT(QUERY_DATE, '%Y-%m-01')
      BETWEEN
          DATE_FORMAT(NOW() - INTERVAL 4 MONTH, '%Y-%m-01')
      AND
          DATE_FORMAT(NOW() - INTERVAL 1 WEEK, '%Y-%m-01')

Кроме того, имейте в виду, что MySQL действительно плохо справляется с диапазонами дат, даже когда поле проиндексировано.Вы, вероятно, закончите полное сканирование таблицы, если не будете осторожны.

4 голосов
/ 05 октября 2015

поздно на вечеринку, но ...

есть способ получить усеченную дату, если вы знаете интервал.Например, если интервал равен MONTH, вы можете получить сегодняшнюю дату (now()), укороченную до месяца, используя следующее:

select date_add('1900-01-01', interval TIMESTAMPDIFF(MONTH, '1900-01-01', now()) MONTH);

Учитывая вышеизложенное, можно создать функцию для уходаа также другие интервалы:

DELIMITER //
create function date_trunc(vInterval varchar(7), vDate timestamp)
returns timestamp
begin
    declare toReturn timestamp;

    if vInterval = 'year' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(YEAR, '1900-01-01', vDate) YEAR);
    elseif vInterval = 'quarter' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(QUARTER, '1900-01-01', vDate) QUARTER);
    elseif vInterval = 'month' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(MONTH, '1900-01-01', vDate) MONTH);
    elseif vInterval = 'week' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(WEEK, '1900-01-01', vDate) WEEK);
    elseif vInterval = 'day' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(DAY, '1900-01-01', vDate) DAY);
    elseif vInterval = 'hour' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(HOUR, '1900-01-01', vDate) HOUR);
    elseif vInterval = 'minute' then set toReturn = date_add('1900-01-01', interval TIMESTAMPDIFF(MINUTE, '1900-01-01', vDate) MINUTE);
    END IF;

    return toReturn;
end//
DELIMITER ;

Используйте это так:

select date_trunc('quarter', now())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...