I Have 2 tables first client_group with data like below
second table client
in Controller I have code like below:
$client = DB::table('client_group')
->where('client_group.user_id','=',$user_id)
->join('client','client_group.client_id','=','client.id')
->select('client_group.*',
'client.client_email',
)->get();
return view('client.group', ['client'=>$client]);
From this query i have results like below:
Illuminate\Support\Collection {#1278 ▼
#items: array:2 [▼
0 => {#1188 ▼
+"id": 1
+"groupname": "testowa grupa"
+"user_id": 2
+"client_id": "4,5,6"
+"created_at": "2021-02-08 13:47:03"
+"updated_at": "0000-00-00 00:00:00"
+"client_email": "test1#wp.pl"
}
1 => {#1123 ▼
+"id": 9
+"groupname": "test2"
+"user_id": 2
+"client_id": "8,14,22"
+"created_at": "2021-01-04 15:19:33"
+"updated_at": null
+"client_email": "test3#wp.pl"
}
]
}
client_id is always in one column ("client_id": "8,14,22") because is added like this.
Now is my question and issues,
how to change view and query to get insted of one email all clients emails? based on client_id, below current view.
At the moment I have only one email first from client_id lists
<td>{{ $row->groupname }}</td>
<td>{{ count(explode(',',$row->client_id)) }}</td>
<td>{{ $row->client_email }}</td>
First of all , use FIND_IN_SET to join table with comma separated values.
Something like this-
DB::table('client_group')
->where('client_group.user_id','=',$user_id)
->join('client',\DB::raw("FIND_IN_SET(client.id,
client_group.client_id)"),">",\DB::raw("'0'"))
->select('client_group.*', \DB::raw("GROUP_CONCAT(client.client_email)
as client_emails"))
->get();
And in the blade file you can get client emails like this-
{{ $row->client_emails }}
Related
I have a table tariff_groups:
id
name
1
Green tariffs
2
Blue tariffs
3
Red tariffs
and I have a table things_usage_tariffs that define which things use which tariffs of a tariff group:
id
thing_id
tariff_group
description
delta
1
1
1
Nice tariff of the Green group.
0
2
1
1
Even nicer tariff of the Green group.
1
3
1
1
Best green tariff.
2
4
1
2
Cool blue tariff.
3
5
1
3
Amazing red tariff.
4
With this code I get all the tariffs that thing with id 1 has:
$tariffs = DB::table('things_usage_tariffs')
->where(
[
'thing_id' => $id,
]
)
->orderBy('delta', 'asc')
->get()
->groupBy('tariff_group')
;
Which returns:
Illuminate\Support\Collection {#1257 ▼
1 => Illuminate\Support\Collection {#1247 ▼
#items: array:4 [▶]
}
2 => Illuminate\Support\Collection {#1253 ▼
#items: array:1 [▶]
}
3 => Illuminate\Support\Collection {#1246 ▼
#items: array:1 [▶]
}
}
Which is cool, but I would like to know how to change the query that I directly get:
Illuminate\Support\Collection {#1257 ▼
'Green tariffs' => array(4)
'Blue tariffs' => array(1)
'Red tariffs' => array(1)
}
I know I could iterate through the result and replace the numeric keys with their respective tariff group name, but for that I would need to make another statement that gets the names and I feel this could be done with a join. Any ideas?
With eloquent and proper relationships:
Two models:
class TariffGroup extends Model{
public function thingsUsageTariffs(){
return $this->hasMany(ThingsUsageTariff::class, 'tariff_group', 'id');
}
}
class ThingsUsageTariff extends Model{
public function tariffGroup(){
return $this->belongsTo(TariffGroup::class, 'id', 'tariff_group');
}
}
Now in your controller:
$tariffs = TariffGroup::with(['thingsUsageTariffs' => function($query){
return $query->orderBy('delta', 'asc');
}])->get();
should yield something similar to what you want to achieve.
If you want to use tables without models, one approach would be to join the tables then apply group by and keyBy to define keys for the groups:
$tariffs = DB::table('things_usage_tariffs')
->join('tariff_groups', 'tariff_groups.id', '=', 'things_usage_tariffs.tariff_group')
->orderBy('things_usage_tariffs.delta', 'asc')
->get()
->groupBy('tariff_group')
->map(function ($group) {
return $group->keyBy('name');
});
This yield should be closer to the result you want.
Note: Name must be unique since we are assigning it as keys. Also, this code is not tested, but I hope this points you in the right direction.
How can I get and display each element from the product json data type in laravel.
"category" => accessories
"product" => "["eyewear", "watches", "shoes"]"
Data has been saved correctly using
$casts = [
'product' => 'array'
];
When I try to display, I get the list like show down
Category :
accessories | Product : ["eyewear", "watches", "shoes"]
Is it possible to get result like
Category : accessories | Product: eyewear *****
Category : accessories | Product: watches *****
Category : accessories | Product: shoes *****
Thanks for your help
Provided the JSON has indeed been successfully converted to an array (in this case to a 1D array), you can get the value for each index like you normally would with any other array:
{{ $product[0] }}
If you want to create some sort of list out of it, you can just loop through it using foreach:
#foreach($product as $p)
{{ "Category: " . $category }}
{{ "Product: " . $p }}
#endforeach
If I understand correctly you already have some query results stored in $items, where you have stored values for category_id and product (based on your original post I assume you've already converted the JSON to an array using the $casts property inside your model, alternatively you could use PHP function json_decode()). If you want to loop through $items, it would probably look like this:
#foreach($items as $item)
#foreach($item['product'] as $product)
{{ "Category: ".$item['category_id']." | Product: ".$product }}
</br>
#endforeach
#endforeach
The code above should output something like this:
Category: 1 | Product: eyewear
Category: 1 | Product: watches
Category: 1 | Product: shoes
Category: 2 | Product: a
Category: 2 | Product: b
Category: 2 | Product: c
I have two tables. Cars and tires. Tires can(!) belong to a car. My tables looks like:
Tires:
id | car_id
-------------
1 | 17
2 | NULL
Cars:
id | name
-------------
17 | BMW
18 | Mercedes
From my understanding, if I want to get all(!) tires (including the car they belong to, if available) I can't create a inner join (so I can't use contain). I need to use a left join. But that way I have no idea how to automatically select all fields on table cars.
Query I do:
$query = $this->Tires->find('all');
$query->leftJoin(
['Cars' => 'cars'],
['Cars.id = Tires.car_id']
);
// brings this SQL query
SELECT Tires.id AS `Tires__id`, Tires.car_id AS `Tires__car_id`
FROM tires Tires
LEFT JOIN cars Cars ON Cars.id = Tires.car_id
But how do I automatically get all fields from cars as well?
UPDATE
burzum actually gave me the solution which I quickly want to detail out since I don't think it is well solved by cake...
In order to achieve what I tried to do, I need to add the following code:
$query
// you need to pass each model you want to get fields for
->select($this->Tires)
->select($this->Tires->Cars);
The car in its tire looks like this:
...
'Cars' => [
'id' => '17',
'name' => 'BMW'
]
...
If I did a contain, it would look like this:
...
'car' => object(App\Model\Entity\Car) {
'id' => (int) 17,
'name' => 'BMW',
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'Cars'
}
...
So, I can work with that. Still, I don't understand the different output...
http://book.cakephp.org/3.0/en/orm/query-builder.html#selecting-all-fields-from-a-table
Example taken from the above URL:
// Only all fields from the articles table including
// a calculated slug field.
$query = $articlesTable->find();
$query
->select(['slug' => $query->func()->concat(['title', '-', 'id'])])
->select($articlesTable); // Select all fields from articles
So in your case you need to pass an instance of the cars table to a select() call.
I am trying to UNION two queries. Here is my code:
public function ledger()
{
$name = Input::get('client');
$invoices = DB::table('invoices')
->where('client',$name)
->selectRaw('`invoiceNumber` as `voucher`,`date`,(`bill` + `ot_bill`) as `amount`');
$cashIns = DB::table('cash_ins')
->where('client',$name)
->select('voucher','date','amount')
->unionAll($invoices)
->get();
return view('cashIn.ledger',compact('cashIns'));
}
But the date is not showing in table. When I check with dd($cashIns) all dates are broken or in a different format. I don't understand what has return in date.
array:3 [▼
0 => {#301 ▼
+"voucher": "JKL02390"
+"date": b"ß\x07\f\x06" //it suppose to be 2015-12-06
+"amount": 23888
}
1 => {#304 ▼
+"voucher": "KL8430" //it suppose to be 2015-10-07
+"date": b"""
ß\x07\n
\x07
"""
+"amount": 98392
}
2 => {#305 ▼
+"voucher": "433"
+"date": b"ß\x07\f\x02" //it suppose to be 2015-12-02
+"amount": 9849
}
]
When I individually dd('invoices') and dd('cashIns') without UNION all dates are well formatted and showing exactly as database.
I am building a popover, in which you can tick checkboxes. The options and choices are stored in a manytomany relationship inside a mysql database.
[ ] option A
[x] option B
[ ] option C
There are 3 tables. sphotos, sphoto_feedback and sphoto_has_feedbacks. sphoto_has_feedbacks stores a sphoto_id, a sphoto_feedback_id and a user_id, to reference the user that has submitted the voting.
sphoto
id | status_id | ...
1 | ...
sphoto_feedback
id | name | ...
11 | Quality |
12 | Creative |
sphoto_has_feedbacks
id | sphoto_id | sphoto_feedback_id | user_id
1 | 1 | 11 | 9999
The Input is user_id => 9999 and sphoto_id => 1. The desired output would be an array, which has all sphoto_feedback entrys, with a boolean variable, like this:
$output = [
"0" => [
"id" => 11,
"name" => "Quality",
"checked" => true
],
"1" => [
"id" => 12,
"name" => "Creative",
"checked" => false
]
]
It would look like this:
[x] Quality <-- stored in sphoto_feedback, also stored in sphoto_has_feedbacks with reference to user
[ ] Creative <-- stored in sphoto_feedback
I want to retrieve all the options from the database and check, if the user has already voted on the options or not.
I know how to do it in PHP with 2 querys, but I'd like to use just one query and would like to know if this is possible.
Use a LEFT JOIN to join the sphoto_feedback and sphoto_has_feedback tables, returning NULL for all the rows in the first table that don't have a match in the second table.
SELECT f.id, f.name, shf.id IS NOT NULL AS checked
FROM sphoto_feedback AS f
LEFT JOIN sphoto_has_feedback AS shf
ON f.id = shf.sphoto_feedback_id
AND shf.sphoto_id = 1 AND shf.user_id = 9999