Display MySQL Query results in Rails App - mysql

Good Day,
Im Looking for some assistance displaying the output of a query result from my MySQL table in the Rails APP.
The DB and Rails are linked and I can Display the full table without issues. How can i Display the following Query results?
Below is the MySQL Query
SELECT
timetable.subject,
timetable.paper
FROM
timetable
WHERE
timetable.`start` < NOW() AND
timetable.`stop` > NOW()
ORDER BY
timetable.`id` ASC
Not Sure if i need to save the query in MySQL and call it from Rails. Or can i acheive this using rails code?

Timetable.where("start < ? AND stop > ?", Time.now, Time.now).order('id ASC').pluck(:subject, :paper)

Related

Mysql Now () is not workig phpmyadmin

I am working on mysql with PHP,I am trying to calculate and fetch estimated time
My following query (static) is working but whenever i try to use dynamic (Use now() in mysql) then not working,
working query is
SELECT TIMESTAMPDIFF(MINUTE,'2019-10-30 16:10:00',ADDTIME(serviceStarted, SEC_TO_TIME(duration*60))) as estimatedTime FROM usr_booking WHERE bookingId='5';
i just repaced current datetime to NOW(),but following query is not working
SELECT TIMESTAMPDIFF(MINUTE,NOW(),ADDTIME(serviceStarted, SEC_TO_TIME(duration*60))) as estimatedTime FROM usr_booking WHERE bookingId='5';
Why NOW() not working in mysql ?

How to get time while querying in mysql?

How can I write this rails query in proper SQL query ?
time = (Time.now - 1.days).beginning_of_day
Assignment.where("created_at >= :time OR updated_at >= :time", time: time).pluck(:assignable_id).uniq
Can you help me to convert this in SQL Query ?
select distinct assignable_id from assignments where created_at >= getDate() && updated_at >= getDate();
I need help in how to get date while querying?
You can get the date using MySQL using CURDATE().
Your query would look like this:
select distinct assignable_id from assignments where created_at >= CURDATE() AND updated_at >= CURDATE();
There is no way to use inequality comparison directly using just ActiveRecord, you will have to use Arel that is a lower level api that ActiveRecord is built on. Luckily you can mix and match them most of the time.
time = (Time.now - 1.days).beginning_of_day
assignments = Assignment.arel_table
Assignment.where(
assignments[:created_at].gteq(time).or(assignments[:updated_at].gteq(time))
).distinct.pluck(:assignable_id)
Passing the current date in from ruby code is a good solution most of the time. However if you do want to use database functions, then Arel is here to help again.
time = Arel::Nodes::NamedFunction.new('getDate', [])
# or
time = Arel::Nodes::NamedFunction.new('CURDATE', [])
# or any other function you can think of
Arel does seem more complicated than just writing raw sql at first glance, but the key is reusability and safety. Arel snippets are easy to reuse by just making them into methods. It's also easy to make injection mistakes using raw sql, Arel will prevent you from making those in most™️ cases.

rails difference between two dates inside .where

Here is my logic
I want to get the closest 4 more expensive mobiles to a specific mobile #mobile but under one condition the difference between the release dates of the two mobiles is not more than a year and half
Here is the query
high = Mobile.where("price >= #{#mobile.price} AND id != #{#mobile.id} AND visible = true").where("ABS(release_date - #{#mobile.release_date}) > ?", 18.months).order(price: :ASC).first(4)
The first .where() works perfectly but the second is not working and I get this error
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '00:00:00 UTC) > 46656000) ORDER BY `mobiles`.`price` ASC LIMIT 4' at line 1: SELECT `mobiles`.* FROM `mobiles` WHERE (price >= 123123.0 AND id != 11 AND visible = true) AND (ABS(release_date - 2016-04-10 00:00:00 UTC) > 46656000) ORDER BY `mobiles`.`price` ASC LIMIT 4
I think now you can get my logic. What is the right syntax to achieve it?
A couple of tips here:
It is a dangerous practice to concatenate variables into your queries using the "#{}" operator. Doing so bypasses query parameterization and could leave your app open to SQL injection. Instead, use "?" in your where clause.
The reason MySQL is giving you an error is because you are concatenating a string into your query without encapsulating it in quotes.
With these two things in mind, I would start by refactoring your query like so:
high = Mobile.where("price >= ?", #mobile.price)
.where.not(id: #mobile.id)
.where(visible: true)
.where("ABS(release_date - ?) > 46656000", #mobile.release_date)
.order(price: :ASC).first(4)
You will note that I replaced 18.months with 46656000. This saves a few clock cycles in the Rails app. Depending on your database schema, the last where clause may not work. The modification below may end up working better.
As a further refinement, you could refactor your last where clause to look for a release date that is between 18 months before #mobile.release_date and 18 months after. The saves your MySql database from having to do the math on each record and may lead to better performance:
.where(release_date: (#mobile.release_date - 18.months)..(#mobile.release_date + 18.months) )
I do not know your database schema, so you may run into date conversion problems with the code above. I recommend you play with it in the Rails console.
Use a Range to query between dates/times:
Mobile.where("price >= ?", #mobile.price)
.where.not(id: #mobile.id)
.where(release_date: 18.months.ago..Time.now)
.order(price: :ASC)
.first(4)

Mysql to eloquent (where multiples row equals a value)

I wish to build a new website based on my old website. To do that i use Laravel 4 (I cannot use Laravel 5 because of the limitations of my hosting).
I have a problem on a MYSQL query that I want to transform into a Laravel Eloquent query.
"SELECT * FROM tbl_sondage WHERE sondage_home='1' AND (sondage_v1+sondage_v2+sondage_v3+sondage_v4+sondage_v5+sondage_v6+sondage_v7+sondage_v8+sondage_v9+sondage_v10) >= 40 ORDER BY RAND()"
Have you an idea of how I can transform this MYSQL Query into Laravel Eloquent Query?
Thank you for your help.
Try something like this:
DB::table('tbl_sondage')->select(DB::raw('tbl_sondage.*,(sondage_v1+sondage_v2+sondage_v3+sondage_v4+sondage_v5+sondage_v6+sondage_v7+sondage_v8+sondage_v9+sondage_v10) AS sumofsondage'))->where('sondage_home', 1)->orWhere('sumofsondage', '>=', 40)->orderByRaw("RAND()")->get();
Not tested

Switched MySQL to Postgres: "column must appear in the GROUP BY clause or be used in an aggregate function"

Switching a rails app from MySQL to Postgres gives the following error:
ERROR: column "contacts.id" must appear in the GROUP BY clause or be used in an aggregate function
Here is the scope in question:
class User < MyModel
def self.top_contacts(timeframe = 1.week.ago, limit = 5)
Contact.unscoped
.where('created_at between ? and ?', timeframe, Time.now)
.group(:user_id)
.order('sum(score) DESC')
.limit(limit)
.includes(:user)
.collect{|x| x.user}
end
end
How to fix this?
Isn't using Rails as the database abstraction layer ensure switching the database should work seamlessly?
The problem is on the level of the SQL, which is invisible from your ORM layer. The problem is exactly with the RoR ORM, because it seems to generate a MySQL-friendly query which uses an extraordinary feature of the MySQL, which postgresql don't have.
The quick solution: give contacts.id to the columns by which you are GROUP-ing as well:
.group("user_id, contacts.id");