How to filter using eloquent using distinct? - laravel

Would like for some help. Currently I have a table with multiple records.
Columns have is : id, identifier, price
I would like to write a query which I'm able to get the unique identifier with the highest price only.
I would like the collection to be
[
[
'id' => 5,
'identifier' => 1001
'price' => 50
],
[
'id' => 7
'identifier' => 1002,
'price' => 35
]
]
the first array id is 5 because from the identifier 1001 the highest price is 50 and the id is 5 and second array id is 7 because identifier 1002 highest price is 35

$maxPrices = Model::select(DB::raw('max(price)'))
->groupBy('identifier')->get();
query result: [50, 35]
Model::select()->whereIn('price',$maxPrices)->orderBy('price', 'desc')->get()
query result
[
[
'id' => 5,
'identifier' => 1001
'price' => 50
],
[
'id' => 7
'identifier' => 1002,
'price' => 35
]
]

Use this to get all distinct identifiers with max price (edit table):
$products = DB::table('tbl_products')->groupBy('identifier')->get(['identifier', DB::raw('MAX(price) as price')]);

Hi guys found a better solution. Read on DB view table. This function will create a virtual table with the value wanted and in laravel you can create a model to reference that virtual table and do eloquent query on it.

Related

Need to Get data of ID ( received in Array ) from database

Good Morning. I am trying to get the data for each BuffaloID which i get in array. From that ID i am trying to get milk record for each buffaloID. But 2nd query give the data for first id only. How can i get the data for each id.
Query
$buffalidforavgmilk = Buffalomilkrecord::groupBy('buffaloID')->get('buffaloID')
->pluck('buffaloID')->toArray();
array:4 [▼
0 => "Buffalo-01"
1 => "Buffalo-02"
2 => "Buffalo-03"
3 => "Buffalo-04"
]
When i try below query i received data only for first id
$avgbuffalomilk = Buffalomilkrecord::where('buffaloID',$buffalidforavgmilk)->
pluck('totalmilk')->toArray();
array:5 [▼
0 => "9.00"
1 => "13.00"
2 => "12.00"
3 => "13.00"
4 => "12.00"
]
I hope i describe my problem and where did i make mistake to get data for all ID
Thanks in Advance
use whereIn
$buffalidforavgmilk = ['1','2','3'];
$avgbuffalomilk = Buffalomilkrecord::whereIn('buffaloID',$buffalidforavgmilk)->pluck('totalmilk')->toArray();

Laravel Query with Sum of value from child table if value column in parent table greater than sum of value in child

I am trying to query for rows from transaction table where the amount is less than sum of allocations against that transaction row in allocations table. This works halfway. It is giving me all transaction queries with an additional field of "allocated_amount".
$all_transactions = Transaction::
withCount([
'allocations AS amount_allocated' => function ($query) {
$query->select(
DB::raw("CAST(SUM(amount) AS INTEGER)"
));
}
])
->where('contact_type','supplier')
->where('contact_id',$ehead->supplier_id)
->get()->toArray();
Result
0 => array:12 [▼
"id" => 4
"amount" => 10000
"created_by" => 1
"amount_allocated" => 7500
]
1 => array:12 [▼
"id" => 5
"amount" => 10000
"created_by" => 1
"amount_allocated" => 10000
]
But I don't want the second result to come up because amount = amount allocated. How to fix this query?
Tried using:
->where('amount','>','allocated_amount')
but maybe because it is additionally added filed, throws an error saying allocated field does not exist. I need it within the query, not as a separate addition.
Well, in this case you can simply use map()
$all_transactions = collect($all_transactions)->map(function ($row) {
if ($row['amount'] > $row['amount_allocated']) {
return $row;
}
})->filter()->toArray(); // filter() to remove null values

how select between tow number 1 and 3 in faker laravel?

I do not need 2 .I want just 1 or 3 in user_id because it is foreign key and have just 1 and 3 number
'user_id' => rand(1,3)->not(2),
'resnumber' => rand(1000000,5000000),
'price' => rand(500000,1000000),
'payment' => rand(0,1),
'created_at' =>$faker->dateTimeBetween('-7 months','now')
You could use randomElement()
'user_id' => $faker->randomElement([1, 3]),
https://github.com/fzaninotto/Faker#fakerproviderbase

ElasticSearch in e-commerce: multiple categories for a product

How do you index products like that in ElasticSearch? We've separated all documents based on the attributes (colour, brand, size, whatever users input), but all of them belong to a set of categories. May be one, may be 15.
[0] => Array
(
[product_id] => 123456
[product_name] => Shirt 1
[filter_name] => Colour
[filter_value] => Blue
[product_parent_id] => 111111
[product_has_discount] => 0
[product_price] => 19.99
[product_stock] => 1
)
[1] => Array
(
[product_id] => 123457
[product_name] => Shirt 1
[filter_name] => Colour
[filter_value] => Red
[product_parent_id] => 111111
[product_has_discount] => 0
[product_price] => 19.99
[product_stock] => 1
)
How would we tag categories into this? Would it be so simple as saying
[product_categories] => ;4750;4834;4835;4836;
And then querying ElasticSearch with match against category with the value ;4836;? Is that possible? Recommended?
You can define product_categories as integer in your mapping and pass in the category values as array like
[product_categories] => array(4750,4834,4835,4836)
EDIT: You read more about mapping here. A more specific to mapping an array type.
Once your data is indexed like that you can query, filter, aggregate on the field product_categories easily in all combinations.
for example to match products in category 4750 or 4750:
{
"filter": {
"terms": {
"product_categories": [
4750,
4750
]
}
}
}

Laravel eager loading returns all results when querying realtionship

I want to get products with a seri name contains a certain word. However it returns all products. Matching serie name condition appears to be array under each related product; for the rest of products it is just a blank "serie" key.
$products=Product::with(array(
'serie'=>function($query)
{
$query->where('name','like','%unky%');
}))
->get()->toArray();
and array returned is like
[0] => Array
(
[id] => 1
[updated_at] => 2014-02-14 22:26:04
[created_at] => 0000-00-00 00:00:00
[brand_id] => 1
[cat_id] => 1
[serie_id] => 1
[devices_ids] => 1
[color_code] => #BEB991
[barcode] => 8699131462430
[title] => Funky Charlie iPhone 5/5S Kılıfı
[desc] => Sert 6 gr
[price] => 29.90
[serie] => Array
(
[id] => 1
[updated_at] => 2014-02-14 22:18:31
[created_at] => 0000-00-00 00:00:00
[name] => Funky
)
)
[1] => Array
(........
[5] => Array
(
[id] => 6
[updated_at] => 2014-02-14 22:46:10
[created_at] => 0000-00-00 00:00:00
[brand_id] => 1
[cat_id] => 1
[serie_id] => 2
[devices_ids] => 1
[color_code] => red
[barcode] => 8699131462546
[title] => Bonjour Kırmızı iPhone 5/5S Kılıfı
[desc] => Sert 6 gr
[price] => 24.90
[serie] =>
As you can see serie key is empty.
What i want is only to bring products with matching serie name and does not bring products like with id"5".
What i am doing wrong?
Thanks
I think that instead of using Model::with(), you want to instead filter the Model, based on the related model, so you should use Model::whereHas()
$products = Product::whereHas('serie', function($query)
{
$query->where('name','like','%unky%');
})->get()->toArray();
Eager loading constraints do not put a constraint on the results of the model - it constraints the related model. In your case, you get all Products. But if you try to access the Series of a Product, you will only get those Series that are true to your condition.
If you need to access the Series too and do not only need the Products, I would make the query like this:
$products=Product::with(array(
'serie'=>function($query)
{
$query->where('name','like','%unky%');
}))
->whereHas('serie', function($query) {
$query->where('name','like','%unky%');
})
->get()->toArray();
In this case, you get only the Products that are linked to a Serie whose name is like %unky% and you get only the related Series that hold to the same condition.
To sum this up: whereHas restricts the list of Products based on the condition, whereas the Eager Loading constraint restricts only the list of Series for each Product.

Resources