代码之家  ›  专栏  ›  技术社区  ›  John

订单日期:日和月

  •  0
  • John  · 技术社区  · 6 年前

    我的用户 birth_date 现在我想查询所有在未来10天内过生日的用户。我不能只点菜 出生日期 因为我会得到这个:

    01-01-1960
    18-12-1975
    16-12-1998
    

    而不是期望的结果:

    16-12-1998
    18-12-1975
    01-01-1960
    

    那么,我怎样才能只订购日和月,而不订购年呢?

    3 回复  |  直到 6 年前
        1
  •  0
  •   Pavel Mikhailyuk    6 年前

    在Ruby方面,首先可以选择所需的用户(PostgreSQL to_char 使用):

    today = Date.current
    dates = (today ... today + 10.days).map { |d| d.strftime('%m%d') }
    dates << '0229' if dates.include?('0228') # update by SteveTurczyn
    users = User.where("to_char(birth_date, 'MMDD') in (?)", dates).to_a
    

    然后对它们进行排序:

    users.sort_by! do |user|
      user_yday = user.birth_date.yday
      user_yday >= today.yday ? user_yday : user_yday + 366
    end
    
        2
  •  1
  •   SteveTurczyn    6 年前

    这在PostgreSQL中有效…

    start_month = Date.today.month
    start_day = Date.today.day
    end_month = (Date.today + 10).month
    end_day = (Date.today + 10).day
    
    if start_month == end_month
        @users = User.where("DATE_PART('month', birth_date) = ? AND DATE_PART('day', birth_date) >= ? AND DATE_PART('day', birth_date) <= ?", start_month, start_day, end_day)
    else
        @users = User.where("(DATE_PART('month', birth_date) = ? AND DATE_PART('day', birth_date) >= ?) OR (DATE_PART('month', birth_date) = ? AND DATE_PART('day', birth_date) <= ?)", start_month, start_day, end_month, end_day)
    end
    @users.order("DATE_PART('month', birth_date), DATE_PART('day', birth_date)")
    

    这将选择在接下来10天内具有生日的所有记录并对其进行排序。

    如果未来的十天仍然是同一个月(比如12月14日),它会选择12月14日到24日之间…如果是在未来一个月(比如12月25日),它会选择12月到月末,1月从开始到第4个月。

        3
  •  1
  •   SteveTurczyn    6 年前

    Ruby实现。请注意,它的性能可能不如DB版本…

    ids_of_next_10_days = User.all.pluck(:id, :birth_date).map do |user_info|
      next_birthday = user_info[1].change(year: Time.now.year) 
      next_birthday = next_birthday.change(year: Time.now.year + 1) if next_birthday < Date.today
      next_birthday.between?(Date.today, Date.today + 10) ? user_info[0] : nil
    end.compact
    
    User.where(id: ids_of_next_10_days)