$customers = DB::table('customers')
->Join('customer_types', 'customer_types.id', '=', 'customers.customer_type')
->Join('countries', 'countries.id', '=', 'customers.country_id')
->select(
'customers.*',
'customer_types.customer_type_name',
'countries.country_name'
)
->get();
foreach ($customers as $result) {
$prices = Pricing::whereIn('id', explode(',', $result->pricelist_id))->get();
}
I have the above code what am trying to achieve is to use the first query to fetch the actual value contained in pricelist_id.
pricelist_id is a collection of many ids ([1, 2, 3]) like that but when I execute the code it returns same value in all rows how can I make it iterate correctly.
You could maybe key your array.
$customers = DB::table('customers')
->Join('customer_types', 'customer_types.id', '=', 'customers.customer_type')
->Join('countries', 'countries.id', '=', 'customers.country_id')
->select(
'customers.*',
'customer_types.customer_type_name',
'countries.country_name'
)
->get();
$prices = []
foreach ($customers as $result) {
$prices[$result->id] = Pricing::whereIn('id', explode(',', $result->pricelist_id))->get();
}
#foreach ($customers as $customer)
{{ $customer->id }},
....
#foreach ($price[$customer->id] as $price)
{{ $price->... }}
#endroreach
#endforeach
This is not ideal. You're making 1 extra query per customer. Instead of having a pricelist_id field in your customers table, you should make it add another table between customers and pricings
+-----------+ +----------+
| customers | +------------------+ | pricings |
+-----------+ | customer_pricing | +----------+
| id |---+ +------------------+ +---| id |
| ... | | | id | | | ... |
+-----------+ +--->| customer_id | | +----------+
| pricing_id |<---+
| ... |
+------------------+
Related
table 1
| ID | val1 |
| 1 | a |
| 2 | b |
| 3 | c |
table 2
| ID | val1 |
| 1 | a |
| 2 | b |
I need to get the table1 data, which is not on table 2
$users_without_info = DB::table('users')->rightJoin('user_infos', 'users.email', '=', 'user_infos.email')
->select('users.*')
->latest()
->get();
I tried this command, doesn't work.
use inner join
$users_without_info = DB::table('users')
->join('user_infos', 'users.email', '!=', 'user_infos.email')
->select('users.*')
->latest()
->get();
if you have models then use relationships with the foreign key then in user model add relation
public function userInfo(){
return $this->hasOne(UserInfo::class);
}
and the query will be
$users_without_info=\App\Models\User::doesntHave('userInfo')->get();
if you don't have foreign key and want to use email as unique identifier then
public function userInfo(){
return $this->hasOne(UserInfo::class,'email','email');
}
Here is the solution,
The issue is in the join statement.
You can try this way to get the table-1(users) data, which is not on table-2(user_infos),
$users_without_info = DB::table('users')
->leftJoin('user_infos', 'users.email', '=', 'user_infos.email')
->whereNull('user_infos.email')
->get();
Hope you will fix it..
Currently having trouble of using groupBy in nested relation on laravel. I have 3 Tables and I want to group the result base on the CountryTbl value. Here are the tables.
UserTbl
----------------------------------
id | name | branch_id |
----------------------------------
1 | Joseph | 1 |
2 | Manuel | 1 |
3 | Margaret | 3 |
----------------------------------
BranchTbl
----------------------------------
id | branch_name | country_id |
----------------------------------
1 | Pampanga | 1 |
2 | Manila | 1 |
3 | California | 2 |
----------------------------------
CountryTbl
------------------------
id | country_name |
------------------------
1 | Philippines |
2 | United States |
------------------------
This is my Model
UserModel
public function branch()
{
return $this->belongsTo('App\Branch');
}
BranchModel
public function country()
{
return $this->belongsTo('App\Country');
}
CountryModel
Now, In the table shown above, I want to get all the users and group them by country.
Here is what I've tried.
public function getAllUsers(){
$users = User::with('branch')
->with(['branch.country' => function($q){
return $q->groupBy('country_name');
}])
->get();
return $users;
}
My code doesn't work. It always returns me an error saying:
Syntax Error or Access Violation
Try this:
User::with(['branch', 'branch.country' => function($q) {
return $q->groupBy('CountryTbl.country_name');
}])
or
User::with(['branch', 'branch.country'])
->get()
->groupBy('branch.country.country_name');
You may try the below code
$data = DB::table('country')
->join('branch', 'country_id', '=', 'country.id')
->join('user', 'branch_id', '=', 'branch.id')
->select('country.country_name','user.name','branch.branch_name')
->groupBy('country.country_name')
->orderBy('country.country_name','ASC')
->get();
I am asked to load data from a single table like the following:
=================================
|id |dept | response | created_at |
=================================
|1 |FO | GOOD | 2018-05-20 |
|2 |FO | GOOD | 2018-05-20 |
|3 |IT | GOOD | 2018-05-20 |
|4 |FO | BAD | 2018-05-20 |
|5 |IT | GOOD | 2018-05-20 |
|6 |LO | BAD | 2018-05-20 |
|7 |IT | GOOD | 2018-05-20 |
|8 |IT | GOOD | 2018-05-21 |
|9 |LO | GOOD | 2018-05-21 |
=================================
they want me to display only records created_at 2018-05-20. and the desired output display in blade is like this:
FO
GOOD 2
BAD 1
IT
GOOD 3
BAD 0
LO
GOOD 0
BAD 1
when I use select distinct, it displays only one row of response data (only GOOD). The same thing happens when I use groupBy
here are my current codes:
Controller:
$date = new Carbon('2018-05-20');
$result = Result::select('dept', 'response')->where('created_at', '=', $date->toDateString())->groupby('dept')->get();
blade:
#foreach($result as $result)
{{$result->dept}}</BR>
{{$result->response}}</br></br>
#endforeach
The output I get:
FO
GOOD
IT
GOOD
LO
GOOD
I don't do the count yet because I still get this undesired result.
Is there a way to achieve the desired request with that single table?
EDIT I:
Based on Yrv16's answer, my controller goes like this:
namespace App\Http\Controllers;
use App\Result;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
public function index()
{
$date = new Carbon('2018-05-20');
$results = Result::select('dept', 'response', \DB::raw('COUNT(*) as count'))
->where('created_at', '=',$date->toDateString())
->groupby('dept','response')
->get();
$results = $results->groupBy('dept');
return view('result.index', compact ('results'));
}
and my blade:
#foreach($results as $result)
{{$result->dept}}</BR>
{{$result->response}}</br></br>
#endforeach
this gives me an empty page. but when i change this where('created_at', '=', $date->toDateString()) to where('created_at', '>=', $date->toDateString()) i get this error Property [dept] does not exist on this collection instance.
Use groupBy for two columns dept, response:
$date = new Carbon('2018-05-20');
$results = Result::select('dept', 'response', \DB::raw('COUNT(*) as count'))
->where('created_at', '=',$date->toDateString())
->groupby('dept','response')
->get();
Also result collection you can groupBy('dept') in order to display it like you want:
$results = $results->groupBy('dept');
Blade:
#foreach($results as $dept => $result)
{{$dept}}</BR>
#foreach($result as $item)
{{$item->response}} {{ $item->count }}
#endforeach
#endforeach
You can use collection manipulation for that:
$results = Result::where('created_at', '2018-05-20')
->get()
->groupBy('dept')
->map(function ($item) {
return $item->groupBy('response')->map(function ($responses) {
return $responses->count();
});
});
It will give you the following results:
print_r($results->toArray());
Array (
[FO] => Array (
[GOOD] => 2
[BAD] => 1
)
[IT] => Array (
[GOOD] => 3
)
[LO] => Array (
[BAD] => 1
)
)
I have this structure.
class Product extends Model{
public function office()
{
return $this->belongsTo(Office::class,'office_id');
}
}
I want to list products order by office.name.
this is the query
$res = \App\Product::with(['office' => function($q){
$q->orderBy('offices.name','asc');
}])->get();
this is the output loop
foreach($res as $key => $val){
print "<br />user: ".$val->id.", office: ".$val->office->id;
}
this is the Product data:
+----+--------+
| id | name |
+----+--------+
| 1 | Life |
| 2 | Cars |
| 3 | Health |
| 4 | House |
+----+--------+
this is the data in Office
+----+----------------+
| id | name |
+----+----------------+
| 1 | First office |
| 2 | working office |
+----+----------------+
The order by is not affecting the result.
same result, the order by like not existed.
Thanks
In your code you are simply "ordering" the offices by name, which means if each product had many offices, it would sort the offices alphabetically.
To sort (OrderBY()) a collection, the column has to be an attribute of the collection object. One solution could be to Join your models. SOmething like this might help you.
$res = Product::with('office')
->join('offices', 'products.office_id', '=', 'offices.id')
->select('products.*', 'offices.name')
->orderBy('office.name')
->get();
messages Table
+----+----------+
| id | text |
+----+----------+
| 1 | message1 |
| 2 | message2 |
+----+----------+
tags table
+----+-----------+
| id | name |
+----+-----------+
| 1 | valentine |
| 2 | funny |
| 3 | santa |
+----+-----------+
message_tag
+----+------------+--------+
| id | message_id | tag_id |
+----+------------+--------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 2 | 2 |
+----+------------+--------+
I have written this query so far to get all messages but i cant return the
message where tag_id = 1;
Message::with([
'tags'=>function($q){
$q->select("name","tag_id");
}
])->select("id", "text")->paginate(10);
i have used where clause inside function($q){$q->where('tag_id',1)}. but it didn't worked.
You have to include use Illuminate\Support\Facades\DB; at the top of class
$tagId = 1;
$return = DB::table('message_tag')
->join('messages', 'messages.id', '=', 'message_tag.message_id')
->join('tags', 'tags.id', '=', 'message_tag.tag_id')
->where("message_tag.tag_id", "=", $tagId)
->select('messages.text', 'tags.text')
->get();
Try using whereHas(), assuming you set a many-to-many relationship properly:
$tag = 'Madhab452';
$messages = Message::whereHas('tags', function ($query) use ($tag) {
$query->where('name', '=', $tag)
->select('name', 'tag_id');
})->get();