MySql високосные годы - PullRequest
1 голос
/ 24 июня 2009

У меня есть таблица MySql под названием «Обзоры», в которой хранится множество обзоров продуктов, накопленных за многие годы, каждая из которых снабжена меткой времени даты.
Я хотел нарисовать гистограмму, показывающую количество отзывов, которые я накопил за каждый день года, в надежде найти важные даты для моей системы.

Я использовал этот запрос

select dayofyear(date),count(*) from reviews group by dayofyear(date);

Однако, заметив, что это возвращает 366 строк вместо 365, я понял, что не могу использовать это для создания этого графика, потому что индекс дня смещается на 1 каждый високосный год, что искажает мои данные.

Например, Рождество показывается как день № 359 в большинстве лет, но его # 360 в високосные годы.

Какой самый простой способ устранить этот перекос?

Есть ли в программном обеспечении какой-либо программный пакет, который может принимать запрос SQL и возвращать результаты непосредственно в виде гистограммы (когда гистограмма имеет смысл)

Ответы [ 2 ]

3 голосов
/ 24 июня 2009

Я не проверял это, но вы могли бы сделать что-то вроде следующего:

SELECT 
        # check if the year is a leap year:
        IF((YEAR(mydate) % 4 = 0 AND YEAR(mydate) % 100 != 0) OR YEAR(mydate) % 400 = 0,
            # if so, check if the date is before or after february 29th. if that is the case, we subtract one from the value
            IF(DAYOFYEAR(mydate) > DAYOFYEAR("2008-02-28"), DAYOFYEAR(mydate) - 1, DAYOFYEAR(mydate)),
            # if the year isn't a leap year, just return the regular dayofyear() value
            DAYOFYEAR(mydate))
    FROM mytbl

Это объединит данные за 28-й и 29-й для високосных лет, но даст одинаковые смещения для дней високосных и не високосных лет для всех остальных дней. Более желательным поведением может быть простое игнорирование данных за 29 февраля, что может быть выполнено с использованием дополнительных условий. Вы также можете назначить ему специальный индекс, например 400, который не будет компенсироваться во все остальные дни.

Лучше было бы группировать по месяцам и дням месяца:

select month(date) m, day(date) d, count(*) from reviews group by m, d;

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

1 голос
/ 24 июня 2009

Группировать их по дням месяца, а затем промывать и повторять для каждого месяца?

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