ORDER BY "the date" Laravel 5 SQL Query - php

I want to sort the results by the date, but this Laravel 5 SQL Query is not working as i want.
$b = DB::table('entry')
->select(DB::raw("DATE_FORMAT(created_at,'%d-%m-%Y') as tanggal"))
->groupBy(DB::raw("DATE_FORMAT(created_at,'%d-%m-%Y')"))
->orderBy(DB::raw("DATE_FORMAT(created_at,'%d-%m-%Y')"), 'asc')
->get();

Here's the easy way to achieve this
Step 1 :
Create a Model named as Entry by artisan command or manually
Step 2 :
Then from your Controller just do
$entry = Entry::orderBy('created_at', 'ASC')->get();
Then you should get the $entry array of what you need.
Hope this helps you

You can still use DB::table and simply put this orderBy. It will work just like the above mentioned.
$query = DB::table('entry')
->select(DB::raw("DATE_FORMAT(created_at,'%d-%m-%Y') as tanggal"))
->orderBy('created_at','ASC')->get(); //either this
->orderBy('updated_at','ASC')->get(); // or this
$query = DB::table('entry')
->select(DB::raw("DATE_FORMAT(created_at,'%d-%m-%Y') as tanggal"))
->orderBy('created_at','DESC')->get(); //either this
->orderBy('updated_at','DESC')->get(); // or this
Note: Either you put 'ASC' or not it will automatically sort it ascendingly.

Related

WhereIn Inside ->where() array - Laravel Query Builder

I'm trying use a whereIn inside a where array I am passing to Laravel query Builder:
$where = [['Participants.Client_Id','IN', $clientId]];
DB::table('Participants')->where($where)->get()
Something like is what I want to achieve, and I know there are works around such as using whereIn, but I'm sharing here a small piece of code to give you an idea, so I need to change the array to make it works as a whereIn, not changing the ->where to ->whereIn or ->whereRaw
DB::table('participants)->whereIn('Participants.Client_Id',$clientId)->get();
You must collect the IDs in the $clientId variables.
If I understand, you could do something like that :
$wheres = [['Participants.Client_Id','IN', [$clientId]]];
$query = DB::table('Participants');
foreach($wheres as $where) {
$query->where($where[0], $where[1], $where[2]);
}
$participants = $query->get();
As laravel document , you can use array in where and each element of this array must be a array with three value . So your $where variable is correct.
But as I searched in operator is not supported by query builder of where.

How to use one query for different selects in laravel?

I thought it would be a good idea to define a query and use it for several selects or counts later, but it does not work. The second select has both wheres in the sql statement:
$query = Pic::where('pics.user_id',$user->id);
if($cat) $query->where('cat',$cat);
if($year) $query->where('jahrprod',$year);
$zb = $query->select('pics.id','pics.title','pics.created_at')
->where('pics.id', '>', $pic->id)
->orderBy('pics.id')
->take(2)
->get()->reverse();
$za = $query->select('pics.id','pics.title','pics.created_at')
->where('pics.id', '<', $pic->id)
->orderBy('pics.id')
->take(13)
->get();
Query:
SELECT `pics`.`id`, `pics`.`title`, `pics`.`created_at`
FROM `pics`
WHERE `pics`.`user_id` = '3'
AND `pics`.`id` > '2180'
AND `pics`.`id` < '2180'
ORDER BY `pics`.`id` ASC, `pics`.`id` ASC
LIMIT 13
I tried to "pass it as reference" i.e. &$query->select... but "only variables can be passed as reference".
How can I use the query , or save it, and use it for both actions. Is it possible?
You are updating object state with the statements when you do $query->where(), so yeah, when you're doing a second select, all conditions from the first one are still there. Thats the reason why these lines work without any assignments:
if($cat) $query->where('cat',$cat);
if($year) $query->where('jahrprod',$year);
To achieve described behaviour you would need to create an query object copy:
$query = Pic::where('pics.user_id',$user->id);
if($cat) $query->where('cat',$cat);
if($year) $query->where('jahrprod',$year);
$queryClone = clone $query;
$zb = $query->select('pics.id','pics.title','pics.created_at')
->where('pics.id', '>', $pic->id)
->orderBy('pics.id')
->take(2)
->get()->reverse();
$za = $queryClone->select('pics.id','pics.title','pics.created_at')
->where('pics.id', '<', $pic->id)
->orderBy('pics.id')
->take(13)
->get();
Notice that mere assignment would not work here:
$queryClone = $query;
Because that would pass object reference and would result in the same behaviour as in your case. Clone creates a full object copy.
http://php.net/manual/en/language.oop5.cloning.php

Laravel modifying multiple rows at once

I have an array of $ids.
I'd like to essentially say:
foreach($ids as $id):
$user = User::find(1);
$user->life_expectancy -= 1;
$user->save();
endforeach;
Except I have thousands of ids in the array, and I'd much rather do something like:
$users = User::whereIn('id', $ids)->update(array('life_expectancy' => --1));
To just get it done in a single query. But that isn't going to work... is there another method?
I know I can update multiple users to all have the same life_expectancy, but I'd like it to be a modification of the previous value.
Check out this site, http://community.sitepoint.com/t/one-sql-statement-to-subtract-and-update-a-field-value/4673 if you decide to use a raw query, but looking on laravel's docs I think you can just do this,
$users = DB::table('users')
->whereIn('id', $ids)->decrement('life_expectancy');
App\User::whereIn('id',[1,2])->decrement('life_expectancy');
If you need -2 use next string:
App\User::whereIn('id',[1,2])->decrement('life_expectancy',2);

RESTful API - Array to Collection Laravel 5

I'm having issues with an array returned from DB::select(). I'm heavily using skip and take on Collections of eloquent models in my API. Unfortunately, DB::select returns an array, which obviously doesn't work with skip and take's. How would one convert arrays to a collection that can utilise these methods?
I've tried
\Illuminate\Support\Collection::make(DB::select(...));
Which doesn't quite work as I expected, as it wraps the entire array in a Collection, not the individual results.
Is it possible to convert the return from a DB::select to a 'proper' Collection that can use skip and take methods?
Update
I've also tried:
$query = \Illuminate\Support\Collection::make(DB::table('survey_responses')->join('people', 'people.id',
'=', 'survey_responses.recipient_id')->select('survey_responses.id', 'survey_responses.response',
'survey_responses.score', 'people.name', 'people.email')->get());
Which still tells me:
FatalErrorException in QueryHelper.php line 36:
Call to a member function skip() on array
Cheers
I would try:
$queryResult = DB::table('...')->get();
$collection = collect($queryResult);
If the query result is an array, the collection is filled up with your results. See the official documentation for the collection. Laravel5 Collections
For anyone else that's having this sort of problem in Laravel, I figured out a work around with the following solution:
$query = DB::table('survey_responses')->join('people', 'people.id', '=', 'survey_responses.recipient_id')
->select('survey_responses.id', 'survey_responses.response', 'survey_responses.score', 'people.name', 'people.email');
if(isset($tags)){
foreach($tags as $tag){
$query->orWhere('survey_responses.response', 'like', '%'.$tag.'%');
}
};
// We apply the pagination headers on the complete result set - before any limiting
$headers = \HeaderHelper::generatePaginationHeader($page, $query, 'response', $limit, $tags);
// Now limit and create 'pages' based on passed params
$query->offset(
(isset($page) ? $page - 1 * (isset($limit) ? $limit : env('RESULTS_PER_PAGE', 30)) : 1)
)
->take(
(isset($limit) ? $limit : env('RESULTS_PER_PAGE', 30))
);
Basically, I wasn't aware that you could run the queries almost incrementally, which enabled me to generate pagination chunks before limiting the data returned.

How to 'order_by' on second table when using eloquent one-to-many

Of course I can use order_by with columns in my first table but not with columns on second table because results are partial.
If I use 'join' everything works perfect but I need to achieve this in eloquent. Am I doing something wrong?
This is an example:
//with join
$data = DB::table('odt')
->join('hdt', 'odt.id', '=', 'hdt.odt_id')
->order_by('hdt.servicio')
->get(array('odt.odt as odt','hdt.servicio as servicio'));
foreach($data as $v){
echo $v->odt.' - '.$v->servicio.'<br>';
}
echo '<br><br>';
//with eloquent
$data = Odt::get();
foreach($data as $odt){
foreach($odt->hdt()->order_by('servicio')->get() as $hdt){
echo $odt->odt.' - '.$hdt->servicio.'<br>';
}
}
In your model you will need to explicitly tell the relation to sort by that field.
So in your odt model add this:
public function hdt() {
return $this->has_many('hdt')->order_by('servicio', 'ASC');
}
This will allow the second table to be sorted when using this relation, and you wont need the order_by line in your Fluent join statement.
I would advise against including the order by in the relational method as codivist suggested. The method you had laid is functionally identical to codivist suggestion.
The difference between the two solutions is that in the first, you are ordering odt ( all results ) by hdt.servicio. In the second you are retrieving odt in it's natural order, then ordering each odt's contained hdt by servico.
The second solution is also much less efficient because you are making one query to pull all odt, then an additional query for each odt to pull it's hdts. Check the profiler. Considering your initial query and that you are only retrieving one column, would something like this work?
HDT::where( 'odt_id', '>', 0 )->order_by( 'servico' )->get('servico');
Now I see it was something simple! I have to do the query on the second table and get contents of the first table using the function odt() witch establish the relation "belongs_to"
//solution
$data = Hdt::order_by('servicio')->get();
foreach($data as $hdt){
echo $hdt->odt->odt.' - '.$hdt->servicio.'<br>';
}
The simple answer is:
$data = Odt::join('hdt', 'odt.id', '=', 'hdt.odt_id')
->order_by('hdt.servicio')
->get(array('odt.odt as odt','hdt.servicio as servicio'));
Anything you can do with Fluent you can also do with Eloquent. If your goal is to retrieve hdts with their odts tho, I would recommend the inverse query for improved readability:
$data = Hdt::join('odt', 'odt.id', '=', 'hdt.odt_id')
->order_by('hdt.servicio')
->get(array('hdt.servicio as servicio', 'odt.odt as odt'));
Both of these do exactly the same.
To explain why this works:
Whenever you call static methods like Posts::where(...), Eloquent will return a Fluent query for you, exactly the same as DB::table('posts')->where(...). This gives you flexibility to build whichever queries you like. Here's an example:
// Retrieves last 10 posts by Johnny within Laravel category
$posts = Posts::join('authors', 'authors.id', '=', 'posts.author_id')
->join('categories', 'categories.id', '=', 'posts.category_id')
->where('authors.username', '=', 'johnny')
->where('categories.name', '=', 'laravel')
->order_by('posts.created_at', 'DESC')
->take(10)
->get('posts.*');

Categories