在日期范围内获取用户生日

时间:2013-03-01 16:01:26

标签: php mysql cakephp

我想获取今天之前和之后3天生日的用户列表。我的意思是,如果今天是March 2,2013,我希望将生日开始Feb 27,2013的用户提升到March 5,2013。这是我的数据库设计。

用户表

id | name | birth_day | birth_month | birth_year

我无法再更改数据库设计,因为我无法访问它,更改设计只会在网站上发生重大变化。

这是我目前的代码:

if (empty($date))
            $date = date('Y-m-d'); // now

        $start_date = strtotime($date.' -'.$day_range.' day');
        $end_date = strtotime($date.' +'.$day_range.' day');
        $start_month = date('m', $start_date);
        $end_month = date('m', $end_date);
        $start_day = date('d', $start_date);
        $end_day = date('d', $end_date);

        if ($start_day > $end_day) {
            $tmp = $start_day;
            $start_day = $end_day;
            $end_day = $tmp;
        }

        /* This is a dirty fix for getting birthdays between dates */
        $this->User->contain(array('User' => array('first_name', 'last_name', 'userstatus_id')));
        $user = $this->User->find('all', array(
            'conditions' => array(
                'User.birth_month BETWEEN ? AND ?' => array($start_month, $end_month),
                'User.birth_day BETWEEN ? AND ?' => array($start_day, $end_day),
            ),
            'fields' => array(
                'birth_year',
                'birth_day',
                'birth_month'
            ),
            'order' => array(
                'birth_month' => 'ASC',
                'birth_day' => 'ASC'
            )
        ));

        foreach($user as $k => $v) {
            $temp = strtotime(date('Y-'.$user[$k]['User']['birth_month'].'-'.$user[$k]['User']['birth_day']));

            if ($temp >= $start_date && $temp <= $end_date) {
            }
            else {
                unset($user[$k]);
            }

        }

2 个答案:

答案 0 :(得分:5)

如果您无法更改表格设计,那么我将从三列创建日期时间,然后将其用于过滤器:

select *
from 
(
  select id, name,
    str_to_date(concat(year(now()), '-', birth_month, '-', birth_day), '%Y-%m-%d') birthdate
  from users
) d
where birthdate >= '2013-02-27'
  and birthdate <= '2013-03-05'

请参阅SQL Fiddle with Demo

这使用STR_TO_DATE()CONCAT()函数创建生日日期作为日期数据类型。获得日期后,即可申请日期过滤器。

答案 1 :(得分:0)

您需要按字母顺序获取日期,以便查询年份,月份和日期。问题是在月初和月末重叠。使用MySQL date formatting options,您可以连接日期并将它们转换为要搜索的日期对象。如果你有很多行,这将是缓慢的,并且效率不高,因为必须对每一行进行评估。

另一种方法是查询您已有的列,但使用从应用程序逻辑中解决的范围条件并生成内联SQL,例如

SELECT * FROM users
WHERE 1=1

然后:

AND birth_year = X

重叠范围的OR

AND (birth_year = X OR birth_year = Y)

对birth_month和birth_day执行相同操作

不是一个优雅的解决方案,但鉴于您的架构设计不佳,我只能看到这两种选择之一。第一个更容易,但第二个应该通常执行得更好,只要查询没有执行全表扫描 - 如果你没有索引,那么只需使用字符串到日期选项。