Laravel db query with now() - mysql

I need to take data from DB, but only when ReturnDate column represents date in the future.
When i do SQL query from DB its working
SQL code:
SELECT * FROM `injuries_suspensions` WHERE `Type` = 'injury' and NOW() < `ReturnDate`
But when i use similar version in Laravel DB query builder, i dont get any data (when i erase where with NOW() i get all data so thats the problem)
Lravel code:
$injuries = DB::table('injuries_suspensions')->where('Type', '=', 'injury')->where(DB::raw('NOW()'), '<', 'ReturnDate')->get();
P.S
dates in DB are far in the future 2020-11-30.

You want to use the simplified version whereRaw instead:
$injuries = DB::table('injuries_suspensions')
->where('Type', '=', 'injury')
->whereRaw('ReturnDate > NOW()')->get(); //see I changed the comparison sides
Observation is that, you're not using whereRaw properly: all should be inside a single string see laravel's example.
You can also pass the timestamp/date directly when building the query, using Carbon see:
use Carbon/Carbon;
....
$injuries = DB::table('injuries_suspensions')
->where('Type', '=', 'injury')
->where('ReturnDate', '>', Carbon::now()->toDateTimeString())->get();
PS: Beware though of timezone difference of your db and your server.

Related

How to query database for rows based on datetime field when I only have the year available to me?

I need to select all rows from a table based on year, however the only field I can query is a DATETIME field that could read e.g. 2020-05-08 14:30:34.
How can I return entries based only off of the year?
$records = MedicalRecord::find()
->where(['dateCreated' => '2020'])
->all();
You can use YEAR() function, try this:
$records = MedicalRecord::find()
->where(['YEAR(dateCreated)' => 2020])
->all();
You can use andWhere() and compare against beginning and end of the year dates.
Probably worth keeping in mind that this would be the equivalent of comparing dates as strings, but since the ordering is YY-mm-dd, it works.
$records = MedicalRecord::find()
->where(['>=', 'dateCreated', '2020-01-01 00:00:00'])
->andWhere(['<', 'dateCreated', '2021-01-01 00:00:00'])
->all();
This way yii generates the code that runs against the database
If you can guarantee that you will be only running your application against a database engine that supports the YEAR() function, then Serghei's answer is probably best. But if you wanted to migrate to PostgreSql, Oracle... It would stop working.

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.

Laravel 5.3 Query - Left join some table

I'm trying to get the most recent record for each candidate_id from a ìnterviews` table.
This is what I want to achive:
I'm using Eloquent on laravel and have already tried this methods (with and without eloquent):
$candidates = DB::table('interviews')->select('interviews.*', 'i2.*')
->leftJoin('interviews as i2',
function ($join) {
$join->on('interviews.candidate_id', '=', 'i2.candidate_id');
$join->on('interviews.created_at', '<', 'i2.created_at');
}
)
->whereNull('i2.candidate_id')
->get();
and with eloquent I've tried this:
$candidates = Interview::leftJoin('interviews as i2',
function ($join) {
$join->on('interviews.candidate_id', '=', 'i2.candidate_id');
$join->on('interviews.created_at', '<', 'i2.created_at');
}
)->whereNull('i2.candidate_id')
->get();
If I change get() to toSql() I have exactly the same query that's shown on the above image, but running on laravel I'm getting always these results (this using the first method, with query builder):
Anyone know why I get this results? Is hard to understand that laravel is doing the same query that I do in HeidiSql but I get diferent results :(
Any tip?
Thanks in advance!
Because you are using ->select('interviews.*', 'i2.*') combined with ->whereNull('i2.candidate_id') I am assuming the second select parameter is overriding all fields on the interviews table with nulls, try reversing the order to ->select('i2.*','interviews.*') or not use the i2.* at all.
This is because the output ignores the alias and only uses the fieldname as element key in the returned collection.
Hope it works.
Perfect case scenario you pick the exact columns you want from each of the joined tables for e.g. it may go like this: table1.id,table1.column1,table1.column2,table2.column2 as smth_so_it_doesnt_override

Writing Query in laravel

Hello i'm new to laravel framework
i have a MySQL query .This work perfectly fine.
select sample.name, ABS((COALESCE(sample.openingbalance, 0)) + COALESCE(trs.TotalAmount, 0)) from sample left join (select ledger,sum(amount) AS TotalAmount from transaction group by transaction.ledger) AS trs on sample.name = trs.ledger
I want to write this query so that it is executed in laravel framework
i tried the following query but its not working
DB::table('sample')->select('sample.name',abs((COALESCE('sample.openingbalance',0))+COALESCE('trs.totalamount',0)))->leftjoin('transaction','sample.name','=','transaction.ledger')->select('ledger','sum(amount) as totalamount')->groupBy('transaction.ledger as trs') ->get();
i think what you need is this.
Raw Expressions
Sometimes you may need to use a raw expression in a query. These expressions will be injected into the query as strings, so be careful not to create any SQL injection points! To create a raw expression, you may use the DB::raw method:
sample code
$users = DB::table('users')
->select(DB::raw('count(*) as user_count, status'))
->where('status', '<>', 1)
->groupBy('status')
->get();
for more info please refer http://laravel.com/docs/5.1/queries#selects

Laravel query build based on relation

I have such query:
Tournament::has('participations', '<', '2')->get();
How can I replace constant number '2' on tournament's column named slots ?? I would like retrieve only these tournaments which have least participants than slots in tournament.
Let's start by using the column name instead of "2". Like you would do in "normal" SQL
Tournament::has('participations', '<', 'slots')->get();
Now, you don't even have to try that because it won't work. But why's that? Because Laravel treats slots like a string and escapes it so SQL does as well.
What you need to do, is use DB::raw(). raw makes sure Laravel changes nothing and just injects it into the SQL query
Tournament::has('participations', '<', DB::raw('slots'))->get();
Update
After some trying out I found this: (Its not very pretty but the only way I got it working)
$subquery = function($q) use ($uid){
$q->where('player_id', $uid);
}
Tournament::whereHas('participations', $subquery)
->whereHas('participations', $subquery, '<', DB::raw('slots'))
->get();
The first whereAs checks for count(*) > 0, the second count(*) < slots and the subquery filters by player id.