Good day. Am trying to query my database to get the child of a child of a child. Every user has 2 children. Am using query builder. The requirements is not to use eloquent and eloquent relationships. But am struggling with it.
$firstchild= DB::table('users') - >where('parent_id', Auth::user() ->id) -> get() ;
$secondchild1 = DB::table('users') - >where('parent_id', $firstchild[0]->parent_id) -> get() ;
$secondchild2 = DB::table('users') - >where('parent_id', $firstchild[1]parent_id) -> get() ;
return view('home' ['firstchild' => $firstchild, 'secondchild1 ' => $secondchild1, 'secondchild2 ' => $secondchild2 , ])
It returns undefined offset 0 if the user child has no child. How do i do it if i want to get without any errors.
If I want to get the children of those children the query results gave, how will I do so?
Try this:
$firstchild = DB::table('users')->where('parent_id', Auth::user()->id)->get();
if ($firstchild->count() == 2) { //**Contains exactly 2 arrays inside the 'firstchild' collection.
$secondchild1 = DB::table('users')->where('parent_id', $firstchild[0]->parent_id)->get();
$secondchild2 = DB::table('users')->where('parent_id', $firstchild[1]->parent_id)->get();
}
return view('home', compact('firstchild', 'secondchild1', 'secondchild2'));
Hope it's helpful.
Related
Hi I am trying to get customer _id from different tables Purchase order ,Sale Order and Consignments
Then I am looping through these Ids . Method I am using for this purpose is working perfectly but . I am afraid if there is a lot of data this method may get failed. Here is my method .
$consignmentCustomerIds = Consignment::select('customer_id')->where('is_repeat', 0)->whereDate('created_at','>',date('2021-03-06'))->whereRaw('(is_group = "parent" or is_group is null)')->where('finalize', 0)->where('invoice_id', null)->distinct()->pluck('customer_id')->toArray();
$poCustomerIds = PurchaseOrder::select('customer_id')->whereDate('created_at','>',date('2021-03-06'))->where('invoice_id', null)->distinct()->pluck('customer_id')->toArray();
$soCustomerIds = SaleOrder::select('customer_id')->whereDate('created_at','>',date('2021-03-06'))->where('invoice_id', null)->distinct()->pluck('customer_id')->toArray();
$spCustomerIds = StoragePeriod::select('customer_id')->whereDate('created_at','>',date('2021-03-06'))->where('invoice_id', null)->distinct()->pluck('customer_id')->toArray();
$ids = array_merge($consignmentCustomerIds, $poCustomerIds, $soCustomerIds, $spCustomerIds);
$customers = Customer::whereIn('id', $ids)->get();
foreach ($customers as $customer) {
CreateInvoiceOneByOne::dispatch($customer)->onQueue('invoice');
}
Is there any better way of doing so?
The main thing is to change ->get() to ->cursor() in the iteration:
// $customers = Customer::whereIn('id', $ids)->get();
$customers = Customer::whereIn('id', $ids)->cursor();
The cursor method may be used to significantly reduce your application's memory consumption when iterating through tens of thousands of Eloquent model records.
More info: https://laravel.com/docs/8.x/eloquent#cursors
IF YOUR RELATIONS ARE SET PROPERLY
I suggest to reduce database query. You can do this by chaning whereHas and orWhereHas within the customer request.
Querying Relationship Existence
$date = date('2021-03-06');
$customers = Customer::whereHas('consignment', function($query) use($date) {
$query->where('is_repeat', 0)->whereDate('created_at','>',$date)->whereRaw('(is_group = "parent" or is_group is null)')->where('finalize', 0)->where('invoice_id', null);
})->orWhereHas('purchase_order', function($query) use($date) {
$query->whereDate('created_at','>',$date)->where('invoice_id', null);
})->orWhereHas('sale_order', function($query) use($date) {
$query->whereDate('created_at','>',$date)->where('invoice_id', null);
})->orWhereHas('storage_period', function($query) use($date) {
$query->whereDate('created_at','>',$date)->where('invoice_id', null);
})->get();
foreach ($customers as $customer) {
CreateInvoiceOneByOne::dispatch($customer)->onQueue('invoice');
}
I set the $date variable before the query, so this way you can manipulate it at one place.
P.S. I am currently assuming the name of the relations.
I’m a beginner in Laravel but have a problem at first. I wrote this query and I’m waiting for Sonya Bins as result but unexpectedly I see ["Sonya Bins"]. what’s the problem?
Route::get('products', function () {
$articles=DB::table('users')->where('id','2')->get()->pluck('name');
return view('products',compact('articles'));
});
pluck will return array if you want to get only single value then use value
// will return array
$articles=DB::table('users')->where('id','2')->get()->pluck('name');
//will return string
$articles=DB::table('users')->where('id','2')->value('name');
// output Sonya Bins
here is an example from the documentation:
if you don't even need an entire row, you may extract a single value from a record using the value method. This method will return the value of the column directly:
$email = DB::table('users')->where('name', 'John')->value('email');
Read more about it here
Hope it helps.
Thanks
pluck() used to return a String before Laravel 5.1, but now it returns an array.
The alternative for that behavior now is value()
Try this:
Route::get('products', function () {
$articles=DB::table('users')->where('id','2')->get()->value('name');
return view('products',compact('articles'));
});
I think it's easier to use the Model + find function + value function.
Route::get('products', function () {
$articles = User::find(2)->value('name');
return view('products',compact('articles'));
});
pluck will return the collection.
I think id is your primary key.
You can just get the first record, and call its attribute's name:
DB::table('users')->where('id','2')->first()->name;
or
DB::table('users')->find(2)->name;
First thing is that you used invalid name for what you pass to view - you don't pass articles but user name.
Second thing is that you use get method to get results instead of first (or find) - you probably expect there is only single user with id = 2.
So to sum up you should use:
$userName = DB::table('users')->find(2)->name;
return view('products',compact('userName'));
Of course above code is for case when you are 100% sure there is user with id = 2 in database. If it might happen there won't be such user, you should use construction like this:
$userName = optional(DB::table('users')->find(2))->name;
($userName will be null if there is no such record)
or
$userName = optional(DB::table('users')->find(2))->name ?? 'No user';
in case you want to use custom string.
I would like to know how to change this entity framework linq query.
I have tableA with the following columns: project (varchar), code (varchar), assess (integer)
the codes data are hierarchical -- i.e 10011, 10012, 10013 ..etc are children of code 1001. Another example 123001, 123002, 12300, 12301 are children of code 1230.
I want query based on project and then go through every rows of code and retrieve all it children with assessment = 0 (for example)
I wrote the below code but it is not giving the correct result:
var result = db.tableA.AsQueryable();
var tempResult = result.Where(p => p.project.Equals(ProjectValue));
result = tempResult.Where(c => c.Code.StartsWith(c.Code) && c.assess== 0);
The query above is not returning the children of the codes where project equal 'ProjectValue'
You need to know which records are the parents in order to do this, if not your condition StartsWith will always be true since you have the children and the parent in tempResult.
I'll assume that the codes with the minimum length are the parents.
After you select the parents you just take all the records that start with the parent code but have different lengths than the parent codes.
var result = db.tableA.AsQueryable();
var minLength = result.Select(t => t.Code.Length).Min();
var tempResult = result.Where(p => p.project.Equals(ProjectValue) && p.Code.Length == minLength);
result = result.Where(c => tempResult.Any(d => c.Code.StartsWith(d.Code)) && c.assess== 0 && c.project.Equals(ProjectValue) && c.Code.Length != minLength);
The closest thing I can think of right now, with the amount of context you've given in your question will end up being:
var result = db.tableA.AsQueryable();
var tempResult = result.Where(p => p.project.Equals(ProjectValue)).select(p => p.code);
result = result.Where(c => tempResult.contains(c.Code.substring(0, 4)) && c.assess== 0 && c.project.Equals(ProjectValue));
I am creating a foreach loop with button attach (name)' for each model which is not connected to the base model with abelongsToMany` relation.
I have an array with IDs for a certain model
$attached_stages = $object->stages()->getRelatedIds()->toArray(); // output: 1, 2
Then I have all model instances for the same model,
$all_stages = Stage::orderBy('id', 'asc')->pluck('id')->all(); // output: 1,2,3,4 ... 6
$missing_stages = array_diff($all_stages, $attached_stages); // output: 3,4,5,6
My question: how to get a collection out of the $missing_stages array
The array is created as expected
My question (alternative solution)
What I am actually trying to get here is a collection of models which are not attached to the main $object with the stages() relation.
The relation is defined as follows:
public function stages()
{
return $this->belongsToMany('App\Models\Stage', 'lead_stage', 'lead_id', 'stage_id')->withPivot('id','status')->withTimestamps();
}
and I am unable to get my desired collection with this code:
$all_stages = Stage::get(); // output: collction 1,2,.... 6
$attached_stages = $object->stages(); // output: 1, 2
$missing_stages = $all_stages->diff($attached_stages); // expected output: 3,4,5,6
Note: I attempted to remove the pivot part in relation definition, but it didn't help, the diff method is not working for me. Nothing is cut from the collection.
Any help appreciated. Thx.
You can use whereNotIn() for your problem as:
$attached_stages = $object->stages()->getRelatedIds()->toArray();
$missing_stages = Stage::whereNotIn('id', $attached_stages)->get();
I need to provide a webservice which returns articles.
I want to include the user relationship in that result to avoid my clients to call another method to load the user object.
I use an Array Result because I want a collection of array (I think it's better to work with) so I wish I could eager load my user.
I tried:
* #ManyToOne(targetEntity="\My\Model\User\User", fetch="EAGER")
But it doesn't look to work.`
Edit, some code:
public function getPublishedArticles($page, $count, $useArrayResult = false) {
$qb = $this->createQueryBuilder('a');
$qb->where('a.status = :status')
->orderBy('a.published_date', 'DESC')
->addOrderBy('a.creation_date', 'DESC')
->setParameter('status', Article::STATUS_PUBLISHED )
->andWhere('a.published_date <= :date')
->setParameter('date', date('Y-m-d'));
}
$adapter = new PaginationAdapter($qb->getQuery());
$adapter->useArrayResult($useArrayResult);
$paginator = new \Zend_Paginator($adapter);
$paginator->setItemCountPerPage($itemCount)
->setCurrentPageNumber($page);
return $paginator;
}
And I call this method with the $useArrayResult flag sets to TRUE
When you're using DQL query you have add JOIN clause to join related entities:
$qb->createQueryBuilder('a')
->addSelect('u')
->join('a.user', 'u')
...
fetch="EAGER" and fetch="LAZY" are being used when you're fetching entities using EntityManager, ie:
$article = $em->find('Entity\Article', 123);