Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> операция с полем типа "дата" 
V
    Опции темы
Aazmandius
Дата 6.9.2006, 18:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


O_o
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 29.4.2006
Где: Vancouver

Репутация: нет
Всего: 6



Помогите пожалуйста с запросом:
есть поле типа дата, там хранятся дни рождения людей, диапазон дат - от 1900 до наших дней, необходимо выбрать поля, день в которых находится в пределах плюс-минус N дней от текущего (месяц учитывается), невзирая на год.(То есть найти людей, у которых день рождения находится в этих пределах на текущий момент). Можно ли это проделать средствами MySQL без сторонних извращений со стороны приложения одним запросом? smile 
Заранее спасибо!
PM WWW   Вверх
muzer
Дата 6.9.2006, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Из того что придумалось:

1.У данного способа есть погрешность плюс минус один день из-за високосных годов.
Код

SELECT * FROM table WHERE DAYOFYEAR(dt) BETWEEN DAYOFYEAR(NOW() - INTERVAL n DAY) AND DAYOFYEAR(NOW() + INTERVAL n DAY)
где dt - колонка даты, n - кол-во плюс-минус дней



2.
Код

SELECT * FROM table WHERE SUBSTRING(dt,5) BETWEEN SUBSTRING(NOW()-INTERVAL n DAY,5) AND SUBSTRING(NOW() + INTERVAL n DAY,5)


Оба варианта не быстрые, т.к. невозможно использовать индекс.
PM WWW   Вверх
Aazmandius
Дата 7.9.2006, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


O_o
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 29.4.2006
Где: Vancouver

Репутация: нет
Всего: 6



Спасибо =)
PM WWW   Вверх
muzer
Дата 7.9.2006, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Эмм..фигню я сказал какую-то..
Проблемы же будут в новый год, точнее всегда, когда даты начала и конца периода будут стоять в разных годах.

Придумал запрос, который решает эту проблему. Но будь я на вашем месте - использовал бы другой способ.

Идея такая: если конец и начало периода стоят в разных годах, то дни рождения первого полугодия ставим выше дней рождений второго полугодия путём прибавления к датам первого полугодия числа 20000, а к датам второго полугодия числа 10000 (чтобы сохранить порядок чисел). К началу периода прибавляем 10000 с той же целью. К концу периода прибавляем 20000, т.к. он должен быть выше начала периода.
Проверял, работает smile

Код

SELECT 
    *
FROM 
    TestTime
WHERE
    SUBSTRING(dt+0,n)
    +IF(
            SUBSTRING((NOW() + INTERVAL n DAY)+0,1,4)>SUBSTRING((NOW()-INTERVAL n DAY)+0,1,4)
        AND 
            SUBSTRING(dt+0,5,2) <= 6
    ,2,1)*10000 
    BETWEEN 
        SUBSTRING((NOW()-INTERVAL n DAY)+0,5)+10000 
    AND 
        SUBSTRING((NOW() + INTERVAL n DAY)+0,5)
        +IF(
            SUBSTRING((NOW() + INTERVAL n DAY)+0,1,4)>SUBSTRING((NOW()-INTERVAL n DAY)+0,1,4)
        ,2,1)*10000;


Но это всё  было проделано мной из спортивного интереса.
Правильное решение на мой взгляд - сгенерить массив дат (месяц-день) за которые надо вывести дни рождения, а потом выполнить запрос 
Код

SELECT * FROM table WHERE SUBSTRING(dt+0,5) IN (наш_массив_через_запятую)

PM WWW   Вверх
Aazmandius
Дата 8.9.2006, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


O_o
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 29.4.2006
Где: Vancouver

Репутация: нет
Всего: 6



Есть еще один способ, недавно придуман =) Суть в том, что мы заменяем все годы, попавшие в выборку, на текущий, и сравниваем с текущей датой, получим как раз искомое значение.
Код

select * from person where CONCAT_WS('-', 'curYear', lpad(month(birthdate),2, '0'), lpad(dayofmonth(birthdate), 2, '0')) between 'begDate' and 'endDate';

где curYear, begDate, endDate - текущий год, нчало и конец диапазона соответственно.
Просто и быстро =)
PM WWW   Вверх
muzer
Дата 8.9.2006, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Да нет же..
Та же проблема, если у нас начало период 2005-12-15 а конец 2006-01-15
Ваш запрос работать не будет.

В этом вся и проблема smile а так-то конечно, это тоже самое, что мой второй вариант из первого поста, только вместо отрезания года - добавляете год smile  Но операций нужно больше, ведь нужно ещё вычислить этот год, а потом ещё к каждой строке его приконкатить, это более сложная операция, чем взять часть готовой строки.

Это сообщение отредактировал(а) muzer - 8.9.2006, 16:47
PM WWW   Вверх
Aazmandius
Дата 8.9.2006, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


O_o
*


Профиль
Группа: Участник
Сообщений: 135
Регистрация: 29.4.2006
Где: Vancouver

Репутация: нет
Всего: 6



Мда, точно =) как то сразу не подумал...
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0528 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.