I need to update single matching record in db (PostgreSQL), but Limit method doesn't work with Update method. This code will update all records matching Where condition instead of single record.
DB::table("records")
->where('need_moderate','=','no')
->where('locked_per_time','<',$date_now->format("Y-m-d H:i:s"))
->limit(1)
->update(["locked_per_time"=>$locked_per->format("Y-m-d H:i:s"),'locked_by'=>$mdkey]);
How do I work around this so only single record would be updated?
Unlike with Oracle or MySQL update statements, using LIMIT directly on PostgreSQL update statements is not possible. So chaining the limit(1) method to the Query Builder instance does nothing, because the compileUpdate method from Laravel's PostgresGrammar class that is responsible for compiling the query, only compiles the where statements.
You could however overcome this by having a condition that uses a subquery which only returns one row that will be updated. Something like this should work:
DB::table("records")->whereIn('id', function ($query) use ($date_now) {
$query->from('records')
->select('id')
->where('need_moderate', '=', 'no')
->where('locked_per_time', '<', $date_now->format("Y-m-d H:i:s"))
->limit(1);
})->update(["locked_per_time" => $locked_per->format("Y-m-d H:i:s"), 'locked_by' => $mdkey]);
The whereIn('id', ...) condition assumes your table has a column named id that can be used as a unique identifier so it can find the first row that matches your conditions in the subquery.
Related
I'm trying to run this update statement, but I get this error:
SQLSTATE[HY000]: General error: 1 no such column: table2.id
DB::table('table1')
->join('table2', 'table1.row_hash', '=', 'table2.row_hash')
->where('table1.some_column', '=', 0)
->whereNull('table1.reference_no')
->update([
'table1.column_to_update' => 1,
'table1.column_to_update_2' => 1,
'table1.column_to_update_3' => 1,
'table1.reference_no' => DB::raw('table2.id') <--comment this line out and it works.
]);
If I comment out that one column from the update statement it works. I've tried using various combinations of quotes and backticks inside of the DB::raw() statement, but still get the same error. This post seems to indicate that I'm doing this the right way, but it's not cooperating.
How can I update the value of table1.reference_no to the value of table2.id? I was hoping to accomplish this in one eloquent query as it's a pretty basic SQL statement. Unfortunately I've also tried using just a raw SQL statement, which yielded other errors despite working when running it directly in my mysql client. This is taking entirely too much time for how simple it should be.
Just stumbled over this.
Putting the values in backticks works. Like this:
'table1.reference_no' => DB::raw('`table2`.`id`')
I want to get the null expiry date result. My whereRaw is working fine but when I used orWhereNull, I get an error. Here is my code:
$offer_details = #\App\Offer::where('store_id',$store_id)->whereRaw('expiry_date > now()')->orWhereNull('expiry_date ')->get();
Following query should work for you as, I don't thing 'orWhereNull()' available in laravel :
$offer_details = #\App\Offer::where('store_id',$store_id)->
->whereNull('expiry_date')
->orWhereRaw('expiry_date > now()')
->get();
Unlike that the "or" variant of 'whereRaw()' is availble as 'orWhereRaw()'.
More details of : whereRaw / orWhereRaw
The whereRaw and orWhereRaw methods can be used to inject a raw where clause into your query. WhereRaw() is a function of Laravel query builder which puts your input as it is in the SQL query's where clause.
For a search query I have the following:
DB::whereRaw('column = ?', 'foo')->orWhereRaw('column IS NULL')->get();
Adding the orWhereRaw statement gives me less results than only the whereRaw. Somehow it seems to ignore the first when adding the other. It is included in the SQL statement. Is there another way to compare for a string and null value?
I have also tried the following, as suggested below:
return self::select('id')
->where('current_state', 'unavailable')
->orWhereNull('current_state')
->get();
If I change the order (the whereNull first and the where second) this also gives me different results. It appears as if the inclusive query doesn't function correctly in correspondence with the where clause. If I use to regular where clauses I don't experience any issues.
Running SELECT * FROM events WHERE current_state='unavailable' OR current_state IS NULL; does produce the correct result for me.
Don't use whereRaw to check for null. You can use this instead:
->orWhereNull('column')
The proper way to do the first where, unless you're doing something extra such as a mysql function, is just to pass the column along like this:
where('column', '=', 'foo')
You can actually eliminate the equals, since it defaults to that. So your query would be:
DB::table('table')->where('column', 'foo')->orWhereNull('column')->get();
I am using Laravel
Let's say, I have two date fields in my table. If I want to compare them, i can do whereRaw clause.
$query->whereRaw('date1 > date2')->get()
Is there a way to make a modification to date2 inside this query, so it is actually date2-1day?
Something like:
$query->whereRaw('date1 > (date2-1day)')->get()
You are free to call any SQL code in the "raw" part of your query, so you could do sth like below:
$query->whereRaw('date1 > DATE_SUB(date2, INTERVAL 1 DAY)')->get();
Keep in mind that executing SQL code this way will make your queries work only in databases that support such functions.
Another way would be using whereColumn like
$users = DB::table('users')
->whereColumn('updated_at', '>', 'created_at')
->get();
OR
UserTable::whereRaw('column1 != column2')->get();
I am trying to do a simple query in doctrine but struggling.
$query->select(array(
'app_title' => 'u.title',
'user_name' => 'u.user_name',
'first_used' => 'MIN(u.creation_time)',
'last_used' => 'MAX(u.stop_time)',
'total_usage' => 'SUM(u.stream_seconds)',
))
->from(self::USAGE_TABLE, 'u')
->orderBy('total_usage', 'DESC');
Obviously I get an error about the column name not being known because Doctrine is using it's own aliases (sclr4).
However, if I try and order by the actual value; SUM(u.stream_seconds), then I get an unexpected bracket in the order by clause, I'm pretty sure SQL doesnt support this.
So, I am simply trying to put data in a table and handle the sorting of the columns. This seems so simple, how do I do it? Any ideas?
You can orderBy the SUM result field by list it in query projection by aliasing result using AS.
If you want to use an aggregate function such as MIN(), MAX(), AVG(), you have to use GROUP BY.
Try simmilar to this, which works perfectly for me (BTW instead of associative array in select method):
$q = $this->em()->createQueryBuilder();
$q->select(['product.id', 'product.title'])
->addSelect('SUM(product.price) AS HIDDEN stat_sum_realised')
->from('ModuleAdmin\Entity\ProductEntity', 'product')
->groupBy('product.id');
$q->orderBy('stat_sum_realised', 'DESC');
Aggregate functions are detailed here (for e.x. for MySQL):
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
As of Doctrine ORM 2.3, you can also use the HIDDEN keyword, which will avoid (in this case) stat_sum_realised from getting hydrated into your resultset.