How do I compare dates using Eloquent in Laravel? - laravel

When I run this code,
$entry_id = Entry::where(function($q)use($intern,$input){
$q->where('interna_id',$intern['id']);
$q->where('created_at','=','2015-06-06');
})->first(['id']);
it gives
select `id` from `entries` where (`interna_id` = 1 and `created_at` = 2015-06-06) limit 1
and as you can see, the date is not enclosed in ''. This causes a problem and MySQL will not be able to find the record. For example, if I add the '', like so,
select `id` from `entries` where (`interna_id` = 1 and `created_at` = '2015-06-06') limit 1
The query is able to retrieve the correct record.
Note:The created_at is using Date format, not DateTime

created_at is of type date for laravel. It uses the Carbon package and expects such an object. You would have to do something like:
$entry_id = Entry::where(function($q)use($intern,$input){
$q->where('interna_id',$intern['id']);
$q->where('created_at','=', Carbon::parse('2015-06-06'));
})->first(['id']);
please note you have to include the library on the page using;
use Carbon\Carbon;enter code here
Alternatively you could use DB::raw for the date as well (untested):
$entry_id = Entry::where(function($q)use($intern,$input){
$q->where('interna_id',$intern['id']);
$q->where('created_at','=', \DB::raw('2015-06-06'));
})->first(['id']);

Related

Laravel unable to update field to null

I can't figure out how to set a field to null on certain condition. It should be an easy query but I'n not able to set the right value for NULL on a nullable field.
Product::where('id', $product_list)->update(['family_id' => null]);
nor
Product::where('id', $product_list)->update(['family_id' => DB::raw(null)]);
did the trick.
Both cases compiled fine but the generated query seems to be wrong because I get a SQL error. In the irst case the error is :
SQLSTATE[HY093]: Invalid parameter number (SQL: update `products` set `family_id` = ?, `products`.`updated_at` = 2019-11-12 08:41:07 where `id` = ?)
and the error for the second one is :
QLSTATE[42000]: Syntax error or access violation: 1064 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 ', `products`.`updated_at` = ? where `id` = ?' at line 1 (SQL: update `products` set `family_id` = , `products`.`updated_at` = 2019-11-12 08:21:50 where `id` = ?)
In the first case it seems that NULL is not being added to the parameters to the prepared query, and in the secon the NULL value is being inserted as nothing in the query. There is any simple way to set the value to NULL?
You should consider the following things first.
1) family_id column is nullable in your table. if not then set nullable.
2) Make sure you have in $fillable property of Product model column family_id.
Make sure $product_list returns id of that particular product.
if $product_list is collection/array of product data then use like:
Product::where('id', $product_list->id)->update(['family_id' => null]);
Try this
Product::where('id', $product_list)->update(['family_id' => 'NULL']);

date method in eloquent querybuilder

i have this raw query and i want to use it in eloquent query builder
but seems i cant use date method in eloquent and gave me this error im new in eloquent. what is the problem:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'date(prizes.created_at), user_id' in 'group statement' (SQL: select user_id,COUNT(user_id), date(created_at) from `prizes` group by `date(prizes`.`created_at), user_id` having `user_id` = 1 order by `date(created_at)` desc)
raw SQL:
SELECT
user_id,COUNT(user_id), DATE(created_at) FROM prizes
GROUP BY DATE(prizes.created_at), user_id
HAVING user_id = 1
ORDER BY DATE(created_at) DESC
limit 2
Eloquent:
$points = \App\Prize::selectRaw('user_id,COUNT(user_id), date(created_at)')
->groupBy("date(prizes.created_at), user_id")
->orderBy("date(created_at)","DESC")
->having("user_id","=",1)
->get();
what is the the cleanest and best form??
By default, Laravel tries to parse all strings as tables. This means it will add the string between `.
To avoid this, you can put the string in a DB:raw() function to let Laravel know not to parse this string and send it as-is to the database.
->orderBy(\DB::raw("date(created_at)"), "DESC")
Or use the raw method for ordering:
->orderByRaw('date(created_at) desc')

Laravel eloquent possible bug?

I want to join two tables and filter on a field in the joined table. I don't think the actual tables matter in this question, but it's a table with dates joined with a table with the event info, so there are more dates possible for 1 event.
I made this eloquent line:
Event_date::whereRaw('startdate >= curdate() OR enddate >= curdate()')->whereHas('Event', function($q){$q->where("approved",true );})->orderBy('startdate', 'asc')->orderBy('enddate', 'asc')->toSql());
the filter doesn't work though. So thats why i added the ->toSql() to the line.
I get the following back:
select * from `event_dates` where startdate >= curdate() OR enddate >= curdate() and exists (select * from `events` where `event_dates`.`event_id` = `events`.`id` and `approved` = ?) order by `startdate` asc, `enddate` asc
You see that the 'where("approved",true )' results in 'where ..... and and approved = ?)' Where does the questionmark come from??? I tried diferent things, like '1', 1, 'True', True, true, 'true'...everything comes back as a questionmark.
Any suggestions??
Thanks!
Erwin
This is expected behaviour. Laravel uses prepared statements. To get parameters that are put into placeholders, you can use
$query->getBindings();
so for example in your case you can use:
$query = Event_date::whereRaw('startdate >= curdate() OR enddate >= curdate()')->whereHas('Event', function($q){$q->where("approved",true );})->orderBy('startdate', 'asc')->orderBy('enddate', 'asc'));
and now
echo $query->toSql();
var_dump($query->getBindings());
to get both query with placeholders and values that will be put in place of placeholders.

how to get latest record from the database having same id in laravel?

I am trying to to get latest record having the same id. For example
I have table
ID | Created_at
1 |2016-04-26
1 |2016-04-20
1 |2016-04-18
2 |2016-04-27
2 |2016-04-19
I want to get result like this
ID | Created_at
1 |2016-04-26
2 |2016-04-27
How do I do this in Laravel? I was only able to order the record by descending order. Don't know how to pick the latest record of each ID. Thank you.
Try using Collections service from laravel , and use last() method. Example:
$data = ModelName::all();
$last_data_object = collect($data)->last();
//try to see the object using var_dump()
var_dump($last_data_object);
I get it from https://laravel.com/docs/5.2/collections#method-last
You can try with whereRaw to getting last records in groupBy laravel
$data = Table::whereRaw('Created_at IN (select MAX(Created_at) FROM table GROUP BY ID)')->get();
Try it this way, it will give you the max grouped ID which will be the latest:
SELECT MAX(ID), Created_at
FROM table
GROUP BY ID, Created_at
Thank you everyone for help. I was able to solve this by
DB::raw("SELECT ID,created_at FROM <table name> a WHERE created_at=(SELECT max(created_at) FROM <table name> b WHERE a.ID=b.ID)
DB::raw('SELECT * FROM `test` WHERE 1 GROUP BY `ID` ORDER BY `Created_at` ASC');
Try this
Include the directive Db
$id = DB::table('your_table')->orderBy('id', 'desc')->value('id');
If you have user_id.
$id = DB::table('your_table')->where('user_id', $user_id)->orderBy('id', 'desc')->value('id');

Laravel - Execute single query with multiple databases

I'm writing an archival function in a Laravel site and I can't figure out how to replicate this query using Laravel's query builder. My databases are 'archive' and 'live'.
INSERT INTO archive.daily_by_post
SELECT post_date, user_id, post_id
FROM live.clicks
WHERE timestamp BETWEEN '2014-07-28 00:00:00' AND '2014-07-28 23:59:59'
GROUP BY user_id, post_id;
Should I use a different method? Is this even possible?
It is possible of course.
However you need to build your query either using raw statement OR Connection::insert() mixed with Query\Builder like below:
$from = '2014-07-30 00:00:00';
$till = '2014-07-30 23:59:59';
$select = DB::table('live.clicks')
->select('post_date', 'user_id', 'post_id')
->whereBetween('updated_at', [$from, $till]) // empty array will do
->groupBy('user_id', 'post_id');
$statement = 'INSERT INTO archive.daily_by_post (specify fields if necessary) '
. $select->toSql();
DB::insert($statement, $select->getBindings());

Resources