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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запрос поиска дня рождения 
:(
    Опции темы
php5
Дата 16.1.2009, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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




Нужно получить   информацию о пользователях    дата рождения которых  попадает в  определенный  интервал,   нашел  след запрос  который выбирает  ближайшие дни рождения на 10 дней.  Так  вроде все работает нормально,  но если  к примеру    в текущий  день нет   дня рождения  а в следящий  есть  то запрос все равно ничего не вернет   т.е он работает  нормально если  в текущий день  (NOW())  в базе есть  чел.  У которого  в этот день  выпадает  день рождения
Как это можно исправить  ?
 
Код

SELECT * 
FROM `tCompanyPersonal` 
WHERE IF (366 - DAYOFYEAR(NOW()) > 10, 
        (DAYOFYEAR(Birthday) - DAYOFYEAR(NOW()) < 10) AND (DAYOFYEAR(Birthday) - DAYOFYEAR(NOW()) >= 0), 
        ((DAYOFYEAR(Birthday) - DAYOFYEAR(NOW()) < 10) AND (DAYOFYEAR(Birthday) - DAYOFYEAR(NOW()) >= 0)) OR ((366 - DAYOFYEAR(Birthday) - DAYOFYEAR(NOW()) < 10) AND (366 - DAYOFYEAR(Birthday) - DAYOFYEAR(NOW()) >= 0)) 

PM MAIL   Вверх
FINANSIST
Дата 16.1.2009, 15:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Статус: Жив
**


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

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



Вообще видится наиболее оптимальным решением нахождение числа N в днях с начала текущего года (01.01.09) до дня рождения в текущем году каждого пользователя. Это даст возможность манипулировать параметрами запроса не только в рамках 10 дней с текущей даты, но и  любыми диапозонами ( например вывести всех  с д.р. в диапозоне с 10 дня с начала года по 75 день с начала года)
Понятно что синтаксис запроса в разных базах будет разный, вот что к примеру у меня получилось в access 
Исходная таблица
Код

Дата          Данные
10.06.1982    aaaaaaa
12.04.1988    ccccccc
30.12.1988    bbbbbbb

Запрос подсчёта к-ва дней (пока без ограничения)
Код

SELECT Таблица1.Дата, Таблица1.Данные, DateSerial(Year(Now()),Month([Таблица1]![Дата]),Day([Таблица1]![Дата]))-DateSerial(Year(Now()),1,1)+1 AS [C начала года до ДР,дней]
FROM Таблица1;

выдает следующий результат
user posted image
Если необходимо выбрать сотрудников с днями рождения между 11 апреля (100 дн) и 30 июня (180) добавляем в запрос ограничение between ( ну или not between)
Код

SELECT Таблица1.Дата, Таблица1.Данные, DateSerial(Year(Now()),Month([Таблица1]![Дата]),Day([Таблица1]![Дата]))-DateSerial(Year(Now()),1,1)+1 AS [C начала года до ДР,дней]
FROM Таблица1
WHERE (((DateSerial(Year(Now()),Month([Таблица1]![Дата]),Day([Таблица1]![Дата]))-DateSerial(Year(Now()),1,1)+1) Between 100 And 180));

получаем следующий результат
user posted image


Это сообщение отредактировал(а) FINANSIST - 16.1.2009, 15:56


--------------------
“...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности”
Эдуард Успенский, “Каникулы в Простоквашино”
PM MAIL ICQ   Вверх
php5
Дата 16.1.2009, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



интересно как это реализовать в mysql  smile 
PM MAIL   Вверх
LSD
Дата 16.1.2009, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 1
Всего: 538



Модератор: а правила почитать влом?
Цитата
Данный форум не предназначен для:
* обсуждения проблем с написание SQL запросов, для этого есть форум Составление SQL-запросов



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
LSD
Дата 16.1.2009, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 1
Всего: 538




M
LSD
Перенесено из баз данных



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
FINANSIST
Дата 16.1.2009, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Статус: Жив
**


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

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



Цитата(php5 @  16.1.2009,  17:06 Найти цитируемый пост)
интересно как это реализовать в mysql 

ХЗ, с мускулом незнаком - я только тебе рабочую логику данного процесса подкинул
Возможно тему теперь придется снова переносить smile 

Это сообщение отредактировал(а) FINANSIST - 16.1.2009, 17:28


--------------------
“...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности”
Эдуард Успенский, “Каникулы в Простоквашино”
PM MAIL ICQ   Вверх
skyboy
Дата 16.1.2009, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Код

SELECT * 
FROM `tCompanyPersonal` 
WHERE date(birthday) between '2008-10-21' AND date_add('2008-10-21', interval 10 days)

вроде так. в смысле, писано "на коленке", и я не уверен, работает ли оператор "between" с данными типа DATE.
PM MAIL   Вверх
php5
Дата 16.1.2009, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



skyboy, разве сюда попадет дата к примеру  1983.10.21  
PM MAIL   Вверх
php5
Дата 16.1.2009, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



нашел для  Mysql  функцию   DATEDIFF  но для того что бы получить строку   2009-01-01 пришлось нагородить следующее   DATE_FORMAT(CONCAT(YEAR(NOW()), '-01', '-01'),'%Y-%m-%d') 
может кто знает как можно  сделать попроще  склейку   того что вернет   YEAR(NOW()  с   '-01-01'   
  
DATEDIFF() returns expr1 – expr2 expressed as a value in days from one date to the other. expr1 and expr2 are date or date-and-time expressions. Only the date parts of the values are used in the calculation. 
mysql> SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');

Это сообщение отредактировал(а) php5 - 16.1.2009, 18:16
PM MAIL   Вверх
skyboy
Дата 16.1.2009, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 15
Всего: 260



Цитата(php5 @  16.1.2009,  16:49 Найти цитируемый пост)
разве сюда попадет дата к примеру  1983.10.21   

нет. я сразу вопрос не понял, извини smile
PM MAIL   Вверх
Akina
Дата 16.1.2009, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 454



а ещё надо учесть, что Now() может дать и 2 января, а чел родился 30 декабря... или наоборот


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
php5
Дата 16.1.2009, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ну в общим получилось у меня  для mysql  следующее 
Код


SELECT us.id_user,  us.fullname , us.birthday FROM user us WHERE   
DATEDIFF(CAST(CONCAT(YEAR(NOW()),DATE_FORMAT(us.birthday,'-%m-%d')) AS DATE), CAST(CONCAT(YEAR(NOW()),'-01-01') AS DATE)) between 
DATEDIFF('2009-01-01',CAST(CONCAT(YEAR(NOW()),'-01-01') AS DATE)) AND
DATEDIFF('2009-01-29',CAST(CONCAT(YEAR(NOW()),'-01-01') AS DATE))

Т.е  на выходе мы получим  клиентов у которых  день рождения находиться между  
'01-01' и '01-29' 


Это сообщение отредактировал(а) php5 - 16.1.2009, 19:07
PM MAIL   Вверх
FINANSIST
Дата 16.1.2009, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Статус: Жив
**


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

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



Цитата(Akina @  16.1.2009,  18:55 Найти цитируемый пост)
а ещё надо учесть, что Now() может дать и 2 января, а чел родился 30 декабря... или наоборот

Для Year(Now()) дата рождения не критична

php5, можно найти решение ещё проще (относительно моего предыдущего)
запросом людей с днём рождения в интервале между 1 го апреля (401) и зо июня (0630) (опять таки на примере Access )
Код

SELECT Таблица1.Дата, Таблица1.Данные, Val(Month([Таблица1]![Дата]) & Day([Таблица1]![Дата])) AS МесДень
FROM Таблица1
WHERE (((Val(Month([Таблица1]![Дата]) & Day([Таблица1]![Дата]))) Between 401 And 630));

получить результат
user posted image

Это сообщение отредактировал(а) FINANSIST - 16.1.2009, 19:13


--------------------
“...Брали корову рыжую одну, отдавать будем корову рыжую одну, чтобы не нарушать отчетности”
Эдуард Успенский, “Каникулы в Простоквашино”
PM MAIL ICQ   Вверх
Deniz
Дата 19.1.2009, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

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



FINANSIST, пример нормальный, но не учитывает переход на новый год, т.е. за неделю в прошлом году с 29.12.2008 по 04.01.2009.
Код
... Between 1229 And 104 ...

Можно предположить, что если year(Начало периода) <> year(конец периода) то можно чуток переделать запрос.
Допустим FN(Дата) - это какая-то функция, которая возвращает дату как число в формате MMDD т.е. 1 апреля = 401
Код
...
where
  (FN(Birthday) between FN(Date_Start) and FN(Date_End)) and (Year(Date_Start) = Year(Date_End))
  or
  (FN(Birthday) >= FN(Date_Start) or FN(Birthday) <= FN(Date_End)) and (Year(Date_Start) < Year(Date_End))
...
как-то так можно попробовать.
PS: нашел ошибку в коде, поправил.

Это сообщение отредактировал(а) Deniz - 23.1.2009, 12:19


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




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


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

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