I have the following model (I'm using ruby on rails) :
# MealSetting model
# week_day:integer
# pick_up_start_time:datetime
# pick_up_end_time:datetime
I want to retrieve all the meals that are available in a certain time, a meal is available if the pick_up_start_time <= current_hour and
pick_up_end_time >= current_hour.
pick_up_start_time:datetime and pick_up_end_time:datetime are actually dates but I'm only using the hours.
I have this query,
MealSetting
.where('pick_up_start_time::time <= ? and pick_up_end_time::time >= ?',
Time.now.utc.strftime("%T"),
Time.now.utc.strftime("%T"))
But it doesn't work because the dates in the database are stored in utc.
You can just use plain SQL and use the now() method.
Since you want to compare the hours inside the dates you can use the date_part function of postgres.
MealSetting.where("date_part('hour', NOW()) BETWEEN date_part('hour', pick_up_start_time) AND date_part('hour', pick_up_end_time)")
I think this is a perfect use case for scopes
class MealSettings < ApplicationRecord
scope :ready_for_pickup, -> { where("hour(pick_up_start_time) <= ?", Time.now.utc.hour) }
scope :before_pickup_ends, -> { where("hour(pick_up_end_time) >= ?", Time.now.utc.hour) }
end
MealSettings.ready_for_pickup.before_pickup_ends
Related
I have DB Update query, I want to update offer_end_dt to a particular date
UPDATE offer SET offer_end_dt = '2020-10-30 00:00:00',
last_update_user_nm = 'testUser',
last_update_tmst = now()
WHERE offer_end_dt LIKE '2020-05-31%';
In above query I have used LIKE because I am not sure about the time.
I ran this query on my test db where I have less record but now I want to run this query on Production DB where we have almost Hundred thousand record.
Is there any way to increase performance of this query? Can I use USE INDEX here? How?
I am using MariaDb.
Assuming that offer_end is a datetime (which it should be), you should do date comparisons:
WHERE offer_end_dt >= '2020-05-31' and offer_end_dt < '2020-06-01';
Have INDEX(offer_end_dt) and do
WHERE offer_end_dt >= '2020-05-31'
AND offer_end_dt < '2020-05-31' + INTERVAL 1 DAY
(With this pattern, there is no need to worry about end-of-month or year, nor leap-year.)
Recently I've used whereBetween to get the date range of both dates but the result is not inclusive in same date. So I come out with this query.
SELECT *
FROM student
WHERE cast(created_at as date) BETWEEN '2019-07-21' AND '2019-07-21'
Now, since I'm just new in laravel. How can I adopt this query to laravel?
Here is my code in laravel:
$student = $this->student
->whereBetween('created_at', ['2019-07-21', '2019-07-21'])
->select('*')
->get()
I dont know how to add cast in whereBetween. Can somebody help me?
I suggest avoiding using the my MySQL CAST() construct and insted include the edge times in both dates. The query will perform better as well.
$student = $this->student
->whereBetween('created_at', ["$from 00:00:00", "$to 23:59:59"])
// If working with Carbon instances
// ->whereBetween('created_at', [$from->format('Y-m-d 00:00:00', $to->format('Y-m-d 23:59:59'])
->select('*')
->get()
You may actually phrase your current query using date literals, and completely avoid the cast to date:
SELECT *
FROM student
WHERE created_at >= '2019-07-21' AND created_at < '2019-07-22'
Laravel code:
$student = $this->student
->where('created_at', '>=', '2019-07-21')
->where('created_at', '<', '2019-07-22')
->select('*')
->get();
Note that this approach leaves the WHERE clause sargable, meaning that an index on the created_at column can be used.
Easy Solution
$student = $this->student
->whereBetween(DB::raw('date(created_at)'), ['2019-07-21', '2019-07-21'])
->select('*')
->get()
So, i´m trying to select rows between two dates.
In db, the dates also have time.
Therefor i need to use LIKE.
SQL
$query = "SELECT * FROM table WHERE date >= LIKE :selectedDateFrom AND <= LIKE :selectedDateTo";
$query_params = array(':selectedDateFrom' => $selectedDateFrom.="%", ':selectedDateTo' => $selectedDateTo.="%");
This one returns error!
How should it look like?
In db, the dates also have time.
Therefor i need to use LIKE.
No, you don't.
To select all date/times where the date component is between (from) and (to), inclusive, you can write it as
SELECT *
FROM table
WHERE date >= :selectedDateFrom
AND date < :selectedDateToPlusOne
(Note the < instead of <=, and set the second parameter to one day after the last day you want to include in your results.) This works even when the column includes times.
you can't use like with dates in SQL
SO use this:
$query = "SELECT * FROM table WHERE date >= :selectedDateFrom AND date <= :selectedDateTo";
You'd strip the time part from a datetime with DATE().
SELECT *
FROM mytable
WHERE date(mydate) >= :selectedDateFrom
AND date(mydate) <= :selectedDateTo;
Or with BETWEEN for better readability:
SELECT *
FROM mytable
WHERE date(mydate) BETWEEN :selectedDateFrom AND :selectedDateTo;
This is my sql query I wont to convert into rails model query
sql : SELECT "vouchers".* FROM "vouchers" WHERE "vouchers"."business_id" = 31 AND '2014-08-20' between start_date and end_date;
My tried model query but this not working please help me to make it working
Voucher.where(["#{Date.today} BETWEEN ? AND ?",:start_date,:end_date])
Try in this format:
data = ModelName.where("today >= from_date AND today <= to_date")
Assuming that start_date and end_date are columns try this version
Voucher.where("current_date between start_date and end_date").where(business_id: 31)
Model.where("DATE(created_at) > :today AND DATE(promoted_till_date) < :two_weeks", today: Date.today, two_weeks: Date.today+14.days)
I have two date columns - from_date and to_date in a database table.
Example:
from_date: 2012-09-10
to_date: 2012-09-30
today: 2012-09-13
I need to fetch all records, if today's date is between from_date and to_date. How do I do that with a SQL query?
If I have loaded the respective record, I can easily decide, if today's date is between from_date and to_date, but I don't know how to fetch those records straight from the database table.
Check the Rails guides on Range conditions:
Client.where(created_at: (Time.now.midnight - 1.day)..Time.now.midnight)
That will produce the following SQL:
SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')
data = ModelName.where("today >= from_date AND today <= to_date")
A secure and easy way to do this would be:
Model.where(':date BETWEEN from_date AND to_date', date: Date.current)
you can use like this:
Data = Model.where("date(now()) between from_date and to_date")
data = ModelName.find(:all, :conditions => "today >= from_date and today <= to_date")
This should do the trick.
today = Date.today
data = ModelName.where("from_date <= ? AND to_date >= ?", today, today)
You could use below gem to find the records between dates,
This gem quite easy to use and more clear By star am using this gem and the API more clear and documentation also well explained.
ModelName.between_times(Time.zone.now - 3.hours, # all posts in last 3 hours
Time.zone.now)
Here you could pass our field also ModelName.by_month("January", field: :updated_at)
Please see the documentation and try it.
Ok, after a long search in google looking for a "rails way" to do a BETWEEN with two date fields and a variable, the most approximate solution I found is creating your own scope to do that.
in your ApplicationRecord write:
class ApplicationRecord < ActiveRecord::Base
scope :between_fields, -> (value, initial_date, final_date) {
where "('#{value}' BETWEEN #{initial_date} AND #{final_date})"
}
end
So now, wherever you need to do a between you can do:
#clients = Client.between_fields(params[:date], :start_date, :final_date)
# SELECT * FROM clients WHERE ('2017-02-16 00:00:00' BETWEEN start_date AND final_date)
You can combine it with others "where" to do your query as specific as you need.