Rails + ActiveRecord: comparing dates - ruby-on-rails

I have a document that has been generated, say, on 2017-10-03 15:02:47.
Then I have this Rails/SQL query (it doesn't matter if I run it through Rails or straight through the SQL console, the results are the same):
SELECT * FROM table where needed_column <= '2017-10-03';
This query would not return me the document that has been generated on 2017-10-03 15:02:47. If I do run, though, this query:
SELECT * FROM table where needed_column <= '2017-10-03 23:59:59';
Then I get the needed document (generated on 2017-10-03 15:02:47).
To solve this issue, I can manually add the time to the query (23:59:59), but it's not a very elegant solution.
I am using Rails 5, AR, PostgreSQL - is there a better way to solve this problem than to manually add the time stamp to the query?
Thank you

Your needed_column is probably saving timestamps (Date and Time). As you already figured it out you need to compare it with another timestamp or cast needed_column using ::date
Model.where("needed_column::date <= '2017-10-03'")
This will generate:
SELECT table.* FROM table WHERE (needed_column::date <= '2017-10-03')

Try this in Rails:-
Model.where(needed_column: [Time.now.at_beginning_of_day, Time.now.end_of_day])
Or as sql query:-
SELECT * FROM table_name WHERE needed_column BETWEEN '2017-10-09 00:00:00 UTC' AND '2017-10-09 23:59:59 UTC'

Related

How can I group selected data by date (timestamp)?

I need to count entries grouped by date (field has TIMESTAMP type in database).
I wrote code
sql = "
SELECT COUNT(id) AS cnt, TO_CHAR(closed_on, 'YYYY-mm-dd') AS closed_on, issues.status_id
FROM issues
WHERE closed_on IS NOT NULL AND closed_on <= '#{end_from_created_date}'
AND created_on <= '#{end_from_created_date}'
GROUP BY closed_on, status_id
"
This query work on postrgesql, but it does not work on sqlite, because sqlite does not have TO_CHAR function
Solution should be compatible with mysql, postgresql, sqlite.
I can use different sql for different DB. But it is not good idea.
May be I can use functions from ActiveRecord, but i do not find solutions in docs
SQLite uses several date formats; PostgreSQL uses similar formats and more.
Both understand YYYY-MM-DD HH:MM:SS.
The solution is
sql = "SELECT COUNT(id) AS cnt, DATE(closed_on) AS closed_on, issues.status_id FROM issues WHERE closed_on IS NOT NULL AND closed_on <= '#{end_from_created_date}' AND created_on <= '#{end_from_created_date}' GROUP BY DATE(closed_on), status_id"

Wonderware Historian: query the Runtime.Events view

I'd like to query the Runtime.Events view with SQL. I have tried the followings:
select * from Runtime.dbo.Events gives the following error:
OLE DB provider "INSQL" for linked server "INSQL" returned message "Event History no longer supports queries that do not provide time".
select * from Runtime.dbo.Events where EventTime >= '2018-09-01 00:00:00' and EventTime <= '2018-11-01 00:00:00' gives this not descriptive error:
Cannot execute the query "..." against OLE DB provider "INSQL" for linked server "INSQL".
The date format seems to be right, because when I have tried with different format I got error referring to wrong date format.
How to query this view?
Perhaps you're trying to query for these events:
SELECT TOP 1000 *
FROM [A2ALMDB].[dbo].[v_EventHistory]
or these events:
SELECT * FROM Runtime.dbo.EventHistory
WHERE DateTime >= '2018-10-11'
I'm unable to clarify this by a comment due to lack of reputation, so let me post an answer. May be your alarms and events are in A2ALMDB database. If that is the case, try the following query.
SELECT * FROM [A2ALMDB].[dbo].Events WHERE [EventStamp] between '2018-09-01 00:00:00' AND '2018-11-01 00:00:00'

Active record, results illustration

Can someone explain this?
Post.where(:p_date => ((Time.now - 7.days)..(Time.now))).count
-> 4507
Post.where(:p_date => ((Time.now - 7.days).beginning_of_day..(Time.now).end_of_day)).count
-> 4794
While p_date is only date type without time.
Thank you
If p_date is a date column, pass dates into your query
Post.where(p_date: (7.day.ago.to_date .. Date.today)).count
which uses this query
SELECT COUNT(*) FROM `posts` WHERE (`posts`.`p_date` BETWEEN '2016-09-08' AND '2016-09-15')
If you pass in time objects, the database will automatically compare against 0:00:00 time (at least on mysql and postgres) which is where you get your discrepancy from.

How to get records by month

I have tried several solutions but the only one close enough to what i want is this
Sale.all.group("DATE_TRUNC('month', created_at)").count
but it returns something like this
{2016-07-01 00:00:00 UTC=>19, 2016-04-01 00:00:00 UTC=>70}
is there something that can do this format?
[month,number of sales] ??
using postgres db.
try use EXTRACT function of postgresql,
in Rails code
results = Sale.all.group("EXTRACT(MONTH FROM created_at").select("EXTRACT(MONTH FROM created_at) AS month, COUNT(*) as count")
p results[0].month if results[0]

RubyOnRails - search in the database by date

I have in my db a attribute where i save the record creation date.
The saved date has this format:
2013/06/18 19:03:24
I need to search only for date and i am not interested the time
I have try in this mode but it's doesn't work:
Report.find_all_by_created_at("2013-06-18").each do |r| %>
[...]
end
Given that created_at is a Rails generated column you can't really and just for created at date. Reason for that is in database created_at is saved as timestamp (or Datetime) so records created on 18th of June may have values from 2013-06-18 00:00:00 to 2013-06-18 23:59:59.
So, if you'd like to select all objects created on specific day you should do something like
Report.where('created_at >= ? AND created_at <= ?, Date.new(2013,6,18).beginning_of_day, Date.new(2013,6,18).end_of_day)
You can pass a range to where:
date = Date.new(2013,6,18)
Report.where(created_at: date.beginning_of_day..date.end_of_day)
This creates a SQL statement like:
SELECT `reports`.* FROM `reports` WHERE `reports`.`created_at` BETWEEN '2013-06-18 00:00:00' AND '2013-06-18 23:59:59'
Probably not the best solution but you could do:
Report.where("created_at >= ? and created_at < ?","2013-06-18","2013,06-19").each do |r|
[...]
end
It looks like you are collecting it as a DateTime and you would probably be able to use the to_date() method to change it to a Date object which would be searchable.
http://api.rubyonrails.org/classes/DateTime.html#method-i-to_date
you can use like matcher in sql query
Report.where("created_at LIKE '2013-06-18%'")
or look at the Squeel gem it can call SQL functions in ruby like syntax then you could use something thati will generate query with
WHERE cast(created_at as date) = '2013-06-18'

Resources