I'm using Laravel 4.2 and have a query builder object. The column I am trying to order by is nullable. When the value is null it treats it as the lowest value. I need to make it treat null as the highest value.
public function sort($builder, $direction = 'asc')
{
return $builder->orderBy('table.nullable_column', $direction);
}
Honestly I just need the null values to be last when sorting ascending and last when descending. Open to suggestions if Laravel doesn't have a way to handle this. Was unable to find anything else using google. Hopefully you guys can help.
Thanks!
Simple put a - sign before the column
public function sort($builder, $direction = 'asc')
{
return $builder->orderBy('-table.nullable_column', $direction);
}
reference: MySQL Orderby a number, Nulls last
Related
I have the following query
Event::where('event_name', $event_id)
->orWhere('id', $event_id)->first();
The $event_id can be a alpha-numeric string (event_name) or an integer (id - primary key). The orWhere statement takes priority over the where statement everytime unless the orWhere statement fails.
For example, the following query gets an event with id = 601, eventhough there is an event that has an event_name = 601a35e0ebee30 with id = 1070.
Event::where('event_name', "601a35e0ebee30")
->orWhere('id', "601a35e0ebee30")->first();
Shouldn't the where statement take precedence over orWhere? Am I missing something?
Also how come a alpha-numeric string work with the primary key (id) which is an unsigened integer?
P.S. When I use Event::find("601a35e0ebee30"), it returns an event with id of 601
use nested array
Event::where([['event_name', $event_id]])->orWhere([['id', $event_id]])->first();
Please try this one.
Event::where(function($query) use ($event_id){
$query->where('event_name', $event_id);
$query->orWhere('id', $event_id);
})->first();
I have a collection called $products, each instance of which has a field created_at. The latter obviously has a format ('Y-m-d H:i:s') in the DB. Now, it's easy to get instances with unique created_at. However, I'd like to retrieve unique year values of created_at in one single expression (that I can write in my view). What I am looking for is:
$products->unique( year value ('Y' ONLY) of 'created_at' )
This expression should evaluate to something like this: ['2012', '2013', '2016'].
Building on the comment that gives you a collection with unique timestamps, you can map out the year and sort with the following code.
$years = $products->unique(function($item){
return $item['created_at']->year;
})->map(function($item){
return $item['created_at']->year;
})->sort()->toArray();
In addition to Tim result
$products = DB::table('products')->get();
$years = $products->unique(function($item){
return $item['created_at']->year;
})->map(function($item){
return $item['created_at']->year;
})->sort()->toArray();
You can use toArray or values() to get the result of collection
This may be a trivial question but I am wondering if Laravel recommends a certain way to check whether an Eloquent collection returned from $result = Model::where(...)->get() is empty, as well as counting the number of elements.
We are currently using !$result to detect empty result, is that sufficient? As for count($result), does it actually cover all cases, including empty result?
When using ->get() you cannot simply use any of the below:
if (empty($result)) { }
if (!$result) { }
if ($result) { }
Because if you dd($result); you'll notice an instance of Illuminate\Support\Collection is always returned, even when there are no results. Essentially what you're checking is $a = new stdClass; if ($a) { ... } which will always return true.
To determine if there are any results you can do any of the following:
if ($result->first()) { }
if (!$result->isEmpty()) { }
if ($result->count()) { }
if (count($result)) { }
You could also use ->first() instead of ->get() on the query builder which will return an instance of the first found model, or null otherwise. This is useful if you need or are expecting only one result from the database.
$result = Model::where(...)->first();
if ($result) { ... }
Notes / References
->first() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_first
isEmpty() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_isEmpty
->count() http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_count
count($result) works because the Collection implements Countable and an internal count() method: http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_count
Bonus Information
The Collection and the Query Builder differences can be a bit confusing to newcomers of Laravel because the method names are often the same between the two. For that reason it can be confusing to know what one you’re working on. The Query Builder essentially builds a query until you call a method where it will execute the query and hit the database (e.g. when you call certain methods like ->all() ->first() ->lists() and others). Those methods also exist on the Collection object, which can get returned from the Query Builder if there are multiple results. If you're not sure what class you're actually working with, try doing var_dump(User::all()) and experimenting to see what classes it's actually returning (with help of get_class(...)). I highly recommend you check out the source code for the Collection class, it's pretty simple. Then check out the Query Builder and see the similarities in function names and find out when it actually hits the database.
Laravel 5.2 Collection Class
Laravel 5.2 Query Builder
I think you are looking for:
$result->isEmpty()
This is different from empty($result), which will not be true because the result will be an empty collection. Your suggestion of count($result) is also a good solution. I cannot find any reference in the docs
I agree the above approved answer. But usually I use $results->isNotEmpty() method as given below.
if($results->isNotEmpty())
{
//do something
}
It's more verbose than if(!results->isEmpty()) because sometimes we forget to add '!' in front which may result in unwanted error.
Note that this method exists from version 5.3 onwards.
There are several methods given in Laravel for checking results count/check empty/not empty:
$result->isNotEmpty(); // True if result is not empty.
$result->isEmpty(); // True if result is empty.
$result->count(); // Return count of records in result.
I think better to used
$result->isEmpty();
The isEmpty method returns true if the collection is empty; otherwise,
false is returned.
According to Laravel Documentation states you can use this way:
$result->isEmpty();
The isEmpty method returns true if the collection is empty; otherwise, false is returned.
I think you try something like
#if(!$result->isEmpty())
// $result is not empty
#else
// $result is empty
#endif
or also use
if (!$result) { }
if ($result) { }
You can do
$result = Model::where(...)->count();
to count the results.
You can also use
if ($result->isEmpty()){}
to check whether or not the result is empty.
so Laravel actually returns a collection when just using Model::all();
you don't want a collection you want an array so you can type set it.
(array)Model::all(); then you can use array_filter to return the results
$models = (array)Model::all()
$models = array_filter($models);
if(empty($models))
{
do something
}
this will also allow you to do things like count().
You can use: $counter = count($datas);
The in_array() checks if a value exists in an array.
public function isAbsolutelyEmpty($value)
{
return in_array($value, ["", "0", null, 0, 0.0], true);
}
You want to check these two cases of count().
#1
If the result contains only a single row (one record) from the database by using ->first().
if(count($result)) {
// record is exist true...
}
#2
If result contain set of multiple row (multiple records) by using ->get() or ->all().
if($result->count()) {
//record is exist true...
}
Seems like such a simple thing, but I can't get my query to return the number of records in a group. Here's my statement:
public function getGroupCount($user_id)
{
$q = Doctrine_Query::create()
->select('ss.*')
->from('SalarySurvey ss')
->where('ss.user_id=?', $user_id)
->groupBy('created_at')
->execute();
return $q->rowCount();
}
rowCount() does not work in the above query.
It might also be helpful to know that this is being used in a foreach statement.
As CappY suggested, this is not possible in Doctrine 1.2, as far as I know. As a work-around, I was able to finally get a count for each grouping by adding another field to the table and setting that field the same for each group at save time. Then I changed my query to pull that field and just did a simple:
$q->count();
Never work with Doctrine 1.2, but can't U use php's count function or SELECT COUNT() AS 'cnt' ?
return count($q);
I've got a method that's meant to return a single value. Because ->result() returns an array I'm using the following to return the single value I'd like to get:
return array_pop($this->db->query($SQL)->result())->event_name;
while it works perfectly fine, I'm wondering if there's something built into CI that maybe I've missed in the documentation. I also use this same trick to return a single record:
return array_pop($this->db->query($SQL)->result());
Is there a better way to do this?
row_array() will return you the 1st row found as an array, and row() will return it as an object.
So instead of array_pop, you can use:
return $this->db->query($SQL)->row()->event_name;
OR
return $this->db->query($SQL)->row_array();
https://www.codeigniter.com/user_guide/database/results.html
When you do what Rocket suggested, you can get a single value by just picking from that array. For example, I used this query to get count of rows:
function getNumberOfArticles() {
$result = $this->db->query("SELECT COUNT(id) AS returnVal FROM articles")->row_array();
return $result['returnVal'];
}