Laravel - get the data in a certain order… - laravel

I have a question about Laravel - Eloquent….
I have a table that has (amongst other things)
id
name (varchar)
position (int)
parent (int) -> id of the parent page (which results in 0 when it is part of the main menu)
My goal didn’t seem to me as difficult but I don’t get it right….
I need to do the following:
Page in position 1
Child 1
Child 2
Page in position 2
Page in position 3
Child 1
Page in position 4
Example Table:
+----+--------+------+
| ID |Position|Parent|
+----+--------+------+
| 1 | 3 | 0 |
| 2 | 2 | 0 |
| 3 | 3 | 6 |
| 4 | 1 | 6 |
| 5 | 2 | 6 |
| 6 | 1 | 0 |
+----+--------+------+
Should result in:
6
- 4
- 5
- 3
2
1
In fact, in my first foreach, I should be able to do this:
if $page->children->count() > 0
I tried a lot of different things, in all ways possible but I don’t get to the result I want……
If someone has a solution for me, I will be happy and very grateful :D
Thank you in advance

If I understand the question correctly, you can read the table data in the controller and you can organize all the data in the view. In the view you can code two nested loops for the two levels you want to show.
Controller:
$items = $table->all();
return view('page', compact('items'));
View page.blade.php:
#foreach($items->where('parent', 0)->sortByDesc('id') as $menuFirstLevel)
{{$menuFirstLevel->id}}
#foreach($item->where('parent', $menuFirstLevel->id)->sortBy('foo-bar') as $menuSecondLevel)
{{$menuSecondLevel->id}}
#endif
#endif

Related

MySQL - Top 5 rank best seller plans or courses

I sell subscriptions of my online course, as well as the courses in retail.
I would bring the "top 5" of best selling plans / courses. For this, I have a table called "subscriptionPlan", which stores the purchased plan ID, or in the case of a course, the course ID, and the amount spent on this transaction. Example:
table subscriptionPlan
sbpId | subId | plaId | couId | sbpAmount
1 | 1 | 1 | 1 | 499.99
2 | 2 | 1 | 2 | 499.99
3 | 3 | 2 | 0 | 899.99
4 | 4 | 1 | 1 | 499.99
Just for educational purposes, plaId = 1 is a plan called "Single Sale" that I created, to maintain the integrity of the DB. When the couId isn't empty, you also have bought a separate course, not a plan where you can attend any course.
My need is: List the top 5 sales. If it is a plan, display the plan name (plan table, column plaTitle). If it is a course, display its name (table course, colna couTitle). This logic that I can't code. I was able to rank a top 5 of PLANS, but it groups the courses, since the GROUP BY is by the ID of the plan. I believe the prank is here, maybe creating an IF / ELSE in this GROUPBY, but I don't know how to do this.
The query that i code, to rank my top 5 plans is:
SELECT sp.plaId, sp.couId, p.plaTitle, p.plaPermanent, c.couTitle, SUM(sbpAmount) AS sbpTotalAmount
FROM subscriptionPlan sp
LEFT JOIN plan p ON sp.plaId = p.plaId
LEFT JOIN course c ON sp.couId = c.couId
GROUP BY sp.plaId
ORDER BY sbpTotalAmount DESC
LIMIT 5
The result that i expected was:
plaId | couId | plaTitle | couTitle | plaPermanent | sbpTotalAmount
1 | 1 | Venda avulsa | Curso 01 | true | 999.98
2 | 0 | Acesso total | null | false | 899.99
3 | 2 | Venda avulsa | Curso 02 | true | 499.99
How could I get into this query formula?
When grouping you can use:
Simple columns, or
Any [complex] expression.
In your case, it seems you need to group by an expression, such as:
GROUP BY CASE WHEN sp.plaId = 1 THEN -1 ELSE sp.couId END
In this case I chose -1 as the grouping for the "Single Plan". You can replace the value for any other that doesn't match any couId.

Laravel many-to-many relationship with varying options

I am new to Laravel and am attempting to set up a many to many relationship (at least I think that's what I need)
Essentially each user have preferences there are 7 types of preferences some preferences can have multiple values and some have only one value
Here are the user_pref_options
project_type | ( will be checkboxes on view and have multiple options)
favorite | (a user can have multiple this is a foreign key to another table)
tagline | ( will be checkboxes on view and have multiple options)
bedroom_min | (a single value per user)
bedroom_max | (a single value per user)
sf_min | (a single value per user)
sf_max | (a single value per user)
and here is what the user_pref table has
| id | user_id | pref_option_id | value |
| --- | --- | --- | --- |
| 1 | 1 | 1 | 5 |
| 2 | 1 | 1 | 3 |
| 3 | 1 | 2 | 364 |
| 4 | 1 | 2 | 201 |
| 5 | 1 | 2 | 9 |
| 6 | 1 | 2 | 244 |
| 7 | 1 | 2 | 192 |
| 8 | 1 | 2 | 292 |
| 9 | 1 | 4 | 1 |
| 10 | 1 | 11 | 1 |
| 11 | 1 | 12 | 6 |
| 12 | 1 | 13 | 1628 |
| 13 | 1 | 14 | 9134 |
so that would be 1 users notice how some option types have multiples
sorry I had to lay a lot of background before I ask my question.
I would like to be able to connect the user prefs to the user using Eloquent and am having trouble figuring out which way it should be done..
here is what I have tried
//User model
public function prefs(){
return $this->belongsToMany('App\Pref', 'pref_user', 'user_id', 'pref_id');
}
and
//Pref Model
public function user()
{
return $this->belongsToMany('App\Pref', 'pref_user', 'user_id', 'pref_id');
}
I have taken a look here
I would like to be able to get all the preferences and display them on a view
(I won't bore you by pasting that in here now)
my struggle is that some of the preferences have multiple options and some have single options. How do I retrieve the values
maybe I need to separate each preference type to its own model but that seems like overkill I am open to suggestions
user_pref table makes it difficult to distinguish between your prefs and also sets a lot of overhead data.
So, you can set the single value prefs (bedroom_min, bedroom_max, sf_min and sf_max) in user model or in separated model and retrieve them with user. And for other prefs, many-to-many relation is better and more flexible.
Finally, When you fetch User model, you will get the model and its relations.

expanding dates outside of current range

I am trying to expand a data set to include dates outside of the current range.
The data I have ranges from 1992q1 to 2017q1. Each observation exists within a portion of that larger window, for example from 1993q2 to 1997q1.
I need to create quarterly observations for each range to fill the missing time. I have already expanded the existing data into quarters.
What I cannot figure out how to do is add in those missing quarters. For example, country1 may have the dates 1993q2 to 1997q1. I need to add in the missing dates from 1992q1 to 1993q1 and 1997q2 to 2017q1.
A very simple analogue of I want I think is your question is shown by this sandbox dataset.
clear
set obs 10
gen id = cond(_n < 7, 1, 2)
gen qdate = yq(1992, 1) in 1
replace qdate = yq(1992, 3) in 7
bysort id (qdate) : replace qdate = qdate[_n-1] + 1 if missing(qdate)
format qdate %tq
list, sepby(id)
+-------------+
| id qdate |
|-------------|
1. | 1 1992q1 |
2. | 1 1992q2 |
3. | 1 1992q3 |
4. | 1 1992q4 |
5. | 1 1993q1 |
6. | 1 1993q2 |
|-------------|
7. | 2 1992q3 |
8. | 2 1992q4 |
9. | 2 1993q1 |
10. | 2 1993q2 |
+-------------+
fillin id qdate
list, sepby(id)
+-----------------------+
| id qdate _fillin |
|-----------------------|
1. | 1 1992q1 0 |
2. | 1 1992q2 0 |
3. | 1 1992q3 0 |
4. | 1 1992q4 0 |
5. | 1 1993q1 0 |
6. | 1 1993q2 0 |
|-----------------------|
7. | 2 1992q1 1 |
8. | 2 1992q2 1 |
9. | 2 1992q3 0 |
10. | 2 1992q4 0 |
11. | 2 1993q1 0 |
12. | 2 1993q2 0 |
+-----------------------+
So. fillin is a simple way of ensuring that all cross-combinations of identifier and time are present. However, to what benefit? Although not shown in this example, values of other variables spring into existence only as missing values. In some situations, proceeding with interpolation is justified, but usually, you just live with incomplete panels.
How to find solutions like these? One good strategy is to skim through the [D] manual to see what basic data management commands exist.

Emit a group only when condition meets

I have requirement to emit all records corresponds to a group, only when a condition is met. Below is the sample data set with alias name as "SAMPLE_DATA".
Col-1 | Col-2 | Col-3
-------------------------
2 | 4 | 1
2 | 5 | 2
3 | 3 | 1
3 | 2 | 2
4 | 5 | 1
4 | 6 | 2
SAMPLE_DATA_GRP = GROUP SAMPLE_DATA BY Col-1;
RESULT = FOREACH SAMPLE_DATA_GRP {
max_value = MAX(SAMPLE_DATA.Col-2);
IF(max_value >= 5)
GENERATE ALL RECORDS IN THAT GROUP;
}
RESULT should be:
Col-1 | Col-2 | Col-3
-------------------------
2 | 4 | 1
2 | 5 | 2
---- ---- ---
4 | 5 | 1
4 | 6 | 2
Two groups got generated. First group is generate because max value of 4,5 is "5"(which meets our condition >=5). Same for second group (6 >= 5).
As I would be performing this operation on big dataset operations like distinct and join would be overkill. For this reason I have come up with pseudo code with one grouping to perform this operation.
Hope I have provided enough information. Thanks in advance.
I would be performing this operation on a huge data set. Doing operation like distinct and join would be overkill on the system. For this reason I have come up with this grouping approach.
Please try the below code and see..
This solution is little lengthy ,but it will work
numbers = LOAD '/home/user/inputfiles/c1.txt' USING PigStorage(',') AS(c1:int,c2:int,c3:int);
num_grp = GROUP numbers by c1;
num_each = FOREACH num_grp
{
max_each = MAX(numbers.c2);
generate flatten(group) as temp_c1, (max_each >= 5 ?1 :0) as indicator;
};
num_each_filtered = filter num_each BY indicator == 1;
num_joined = join numbers BY c1,num_each_filtered by tem_c1;
num_output = FOREACH num_joined GENERATE c1,c2,c3;
dump num_output;
O/p:
Col-1 | Col-2 | Col-3
-------------------------
2 | 4 | 1
2 | 5 | 2
---- ---- ---
4 | 5 | 1
4 | 6 | 2

Oracle hierarchical query join to selection of all decendants

I am trying to retrieve a list of each descendant with each item.
I am not sure I am making sense, I will try and explain.
Example Data:
ID | PID
--------
1 | 0
2 | 1
3 | 1
4 | 1
5 | 2
6 | 2
7 | 5
8 | 3
etc...
The desired results are:
ID | Decendant
--------------
1 | 1
1 | 2
1 | 3
1 | 4
...
2 | 2
2 | 5
2 | 6
2 | 7
3 | 3
3 | 8
etc...
This is currently being achieved by using a cursor to move through the data and inserting each descendant into a table and then selecting from them.
I was wondering if there was a better way to do these, there must be a way to right a query that would bring back the desired results.
If any one has ideas, or has figured this out before it would be very appreciated. Ordering is not important, nor is the 1 - 1, 2 -2 reference. It would be cool to have it, but not crucial.
select connect_by_root(id) as ID, id as Decendant
from table1
connect by prior id = pid
order by 1, 2
fiddle
Here is my attempt! Not sure, if I got you right!
select pid ,connect_By_root(id) as descendant from process
connect by id = prior pid
union all
select distinct pid,pid from
process
order by pid,descendant

Resources