How to use substr() inside an orderBy function in Laravel - php

Good day,
I need to sort my result by using "orderBy" function in laravel but unfortunately the values in that column that I want to use has "j1_" before the actual number.. so I want to remove the first 3 character first but when I tried
orderBy(substr('x_fs_format_details.tree_xid', 3))
it gives me a "Column not found" error.
Is there a way to tweak this? thanks.

I'm assuming you use MYSQL (the substring function might be different on other databases)
You can either make a new field on the fly:
$query->selectRaw('*, SUBSTR(x_fs_format_details.tree_xid, 3) AS substr_tree_xid')
->orderBy('substr_tree_xid')->get();
This has the advantage/disadvantage that the result of SUBSTR will be in your result. If you don't want that you can also use SUBSTR in the order by directly:
$query->orderByRaw('SUBSTR(x_fs_format_details.tree_xid, 3)')->get();

Related

how to use php method like "explode" in sql

I am trying to get some data, and in the table, there is a field named "sysload". However, it is a var(string) type. The data in it is like "0.0, 0.2, 0.5",three numbers split by comma. However, in the sql, I only need the last number(in this example:0.5) to compare in "where". So how can I use it ? My code:
$termquery=mysql_query("SELECT a.terminal FROM terminal_server_log a
inner join
(
SELECT terminal, MAX(timestamp) timestamp
FROM terminal_server_log
group by terminal
) b on (b.terminal=a.terminal and a.timestamp=b.timestamp)
WHERE explode(',', sysload)[2]>$number");
The last line is the most important one, i want to compare with '$number', but it seems i cannot use 'explode'. Thanks
You can probably use regular expressions to match the last element of your sysload column: https://dev.mysql.com/doc/refman/8.0/en/regexp.html#function_regexp-instr
Look also at CAST() function, as the extracted substring should be converted to a numeric value to allow comparison with a number.
PHP functions will not work inside SQL queries.
You can remove this filter from your query and filter at the php side, or you can make a custom explode function using some mysql string functions.
In this link has an example: (I didn't check if it's working)
Equivalent of explode() to work with strings in MySQL

Eloquent whereRaw statement and orWhereRaw is NULL

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();

How to write MySQL Query in Laravel 5 without using PHP String function?

I need to eliminate the specific prefix of a string by default on getting value from the database.
In MySQL, i can use the following,
SELECT RIGHT('abc3',1) -- Results in "3"
SELECT RIGHT('abc3',2) -- Results in "c3"
But, how can i use same process in Laravel eloquent?.
Or any other solutions are available for remove the prefix of a string while retrieve from database in laravel.
I know trim will eliminate, but only spaces.
ex.
property_color
property_size
Here i need to extract "property_".
expect.
color
size
Is it possible in laravel, in without using PHP String function.
Only on Direct eloquent Operation.
Thanks in Advance !
That's what I would do:
$arrayData = DB::select(DB::raw("SELECT RIGHT('abc3',1) ")):
you can pass array of parameter to bind values:
DB::select(DB::raw(" SQL QUERY "),$paramsArray);
You have to use raw queries within your builder like
$results = YourRepo::where(DB::raw("SELECT SUBSTRING('property_color',9)") , 'LIKE', "%property_xxx%");
keep in mind that substring is slow.

Using two columns in where Laravel ORM

I have two columns in my table: max and current. I want to build simple scope
public function scopeNotMax($query)
{
return $query->where('max', '>', 'current');
}
But Laravel gives me that query:
SELECT * FROM table WHERE `max` > 'current'
I don't want this result and I know that I can use in this place whereRaw() or DB::raw(). But I can't find another way to say "hey, this is column, not string!'. Can I do it? Or I must use raws? I want to avoid it.
There is no other way.
where() method in this case add third parameter (value) to bindings and passes it ot PDO library. So it will be escaped.
Alternatively You can pass as third parameter a Closure, but then laravel will form a sub-select for You, which doesn't helps much.
Looks like whereRaw() is made for this kind of sitiuation.
Did you give a try with this ? return $query->where('max > current');
you can use whereRaw():
->whereRaw('table_1.name = table_2.name');
You exmaple code:
->whereRaw('max>current');

Laravel: How to get last N entries from DB

I have table of dogs in my DB and I want to retrieve N latest added dogs.
Only way that I found is something like this:
Dogs:all()->where(time, <=, another_time);
Is there another way how to do it? For example something like this Dogs:latest(5);
Thank you very much for any help :)
You may try something like this:
$dogs = Dogs::orderBy('id', 'desc')->take(5)->get();
Use orderBy with Descending order and take the first n numbers of records.
Update (Since the latest method has been added):
$dogs = Dogs::latest()->take(5)->get();
My solution for cleanliness is:
Dogs::latest()->take(5)->get();
It's the same as other answers, just with using built-in methods to handle common practices.
Dogs::orderBy('created_at','desc')->take(5)->get();
You can pass a negative integer n to take the last n elements.
Dogs::all()->take(-5)
This is good because you don't use orderBy which is bad when you have a big table.
You may also try like this:
$recentPost = Article::orderBy('id', 'desc')->limit(5)->get();
It's working fine for me in Laravel 5.6
I use it this way, as I find it cleaner:
$covidUpdate = COVIDUpdate::latest()->take(25)->get();
Ive come up with a solution that helps me achieve the same result using the array_slice() method. In my code I did array_slice( PickupResults::where('playerID', $this->getPlayerID())->get()->toArray(), -5 ); with -5 I wanted the last 5 results of the query.
The Alpha's solution is very elegant, however sometimes you need to re-sort (ascending order) the results in the database using SQL (to avoid in-memory sorting at the collection level), and an SQL subquery is a good way to achieve this.
It would be nice if Laravel was smart enough to recognise we want to create a subquery if we use the following ideal code...
$dogs = Dogs::orderByDesc('id')->take(5)->orderBy('id')->get();
...but this gets compiled to a single SQL query with conflicting ORDER BY clauses instead of the subquery that is required in this situation.
Creating a subquery in Laravel is unfortunately not simply as easy as the following pseudo-code that would be really nice to use...
$dogs = DB::subQuery(
Dogs::orderByDesc('id')->take(5)
)->orderBy('id');
...but the same result can be achieved using the following code:
$dogs = DB::table('id')->select('*')->fromSub(
Dogs::orderByDesc('id')->take(5)->toBase(),
'sq'
)->orderBy('id');
This generates the required SELECT * FROM (...) AS sq ... sql subquery construct, and the code is reasonably clean in terms of readability.)
Take particular note of the use of the ->toBase() function - which is required because fromSub() doesn't like to work with Eloquent model Eloquent\Builder instances, but seems to require a Query\Builder instance). (See: https://github.com/laravel/framework/issues/35631)
I hope this helps someone else, since I just spent a couple of hours researching how to achieve this myself. (I had a complex SQL query builder expression that needed to be limited to the last few rows in certain situations).
For getting last entry from DB
$variable= Model::orderBy('id', 'DESC')->limit(1)->get();
Imagine a situation where you want to get the latest record of data from the request header that was just inserted into the database:
$noOfFilesUploaded = count( $request->pic );// e.g 4
$model = new Model;
$model->latest()->take($noOfFilesUploaded);
This way your take() helper function gets the number of array data that was just sent via the request.
You can get only ids like so:
$model->latest()->take($noOfFilesUploaded)->puck('id')
use DB;
$dogs = DB::select(DB::raw("SELECT * FROM (SELECT * FROM dogs ORDER BY id DESC LIMIT 10) Var1 ORDER BY id ASC"));
Dogs::latest()->take(1)->first();
this code return the latest record in the collection
Can use this latest():
$dogs = Dogs::latest()->take(5)->get();

Categories