I’m using PHP to dynamically add another table to a page based on a parent/child relationship.
I’ve greatly simplified things so lets suppose I have a table 'FAMILY' with three columns Parent Int(6), Child varchar(15), and Fname varchar(25). The table has four rows, whose values are;
Row 1 : 4, NULL , Bill
Row 2: 5, 4, Tom
Row 3: 6, NULL, Frank
Row 4: 7, 4, Sam
As you can tell Tom and Frank are children of Bill. And so Bill is the parent of Tom and Sam.
Regardless of whose record I’m currently looking at, I would like to be able to dynamically see the other associated records as well. Forget the PHP part, I have that working. I just need the MySQL query.
The way I see it, I need one query that will do two different things depending on the value of child.
1: If Child is NULL (or blank) as in Row 1, I need it to return Row 2 and 4 based on the parent value of 4. In other words I’m looking at a Parent.
2) If Child is NOT NULL, as in Rows 2 & 4, I need it to return row 1 and the other row 2 or 4 depending which child I was looking at. Now I’m looking at a child record.
SELECT * FROM FAMILY WHERE
CASE WHEN Child IS NOT NULL then parent = 4
WHEN child IS NULL then child = 4
END
GROUP BY PARENT
I’m pretty sure that I’m using CASE/WHEN incorrectly but after trying about a thousand things I give up and need to ask for help.
Please a MySQL query that can evaluate if it’s a parent or child and then pull the appropriate row(s) would be very much appreciated.
Thanks in advance.
Not much sure from your question statement but you can modify your WHERE condition to be like below
WHERE (Child IS NOT NULL AND parent = 4)
OR COALESCE(child, 4) = 4
Related
This is going to be a long shot, but I have been staring at this for longer then I should have... I have a structure setup like this:
C (hasMany) B (hasMany) A
1 1 1
2 2 2
3 3 3
4 4 4
Where each character is a table, and each number a field of said table record. Field 1 is the primary key called 'id'. My function only takes a single argument, lets call it $X. The following is what should happen:
Find the first record in table C, where field 3 has value $X
Find the first record in table B, where field 2 has the value of A record's field 1
select fields 3 and 4 in table A of all records, where field 2 has the value of B record's field 1
Working with CakePHP has been a blessing with it's more then decent documentation, but beside my lack of properly understanding associations, I find it extremely difficult to make this work recursivly. What am i dong wrong here?
So far ive tried a few variations of the following:
$tableC->find('all')
->select(['val1'=>'A.3',
'val2'=>'A.4',
])
->where(['C.3 = ' => $X])
->innerJoinWith('B')
->innerJoinWith('A')
->toList()
;
I can get whatever values I want from the B table, but anything further then that is where I start getting errors like:
The A association is not defined on C.
Is there anyone that could shed some light on this? Im using CakePHP 3.9.
Thanks in advance!
I am making the function of importing data from the excel file with the following structure
i want loop the datas of excel then insert to categories table and determined subcategory by value of first column. Eg: 101 is sub category of 1, 101001 is sub of 101,...
I have been thinking for a long time and looking for it but not yet. Hope the helping.
Use PHP Spreadsheet https://phpspreadsheet.readthedocs.io/en/latest/
Reading from a file: https://phpspreadsheet.readthedocs.io/en/latest/topics/reading-files/#reading-files
However you parse the cat/subcat, you would want to insert it back into the table with the database ID of the parent.
To determine the parent, start with the first row, and keep it in a parents array. When you hit the next row, check the parents array if the value exists. You will have to check char by char. Then add every new category to the parents. This structure is not really ideal, what happens when PHP becomes a parent, and so on. PHP should be 10101 at any rate to follow the structure. Ruby 10102
In all honesty, you don't need second half of the number, only the parent. Just use the row id.
1, , Programming
2,1,OOP
3,2,PHP
What you are missing here is the row id. The last part is only the "sort" and can just be removed. Imagine if the column was a fixed length field which would be "easier" to parse. 3 digit for parent, and 3 digits for the sort. Start parsing from the top ..
000001 Programming
001001 OOP
What is PHP now? You aren't pointing to 001 (OOP) cause 001 is also Programming. So adding a row id, you can now point to the id that will be entered into the DB.
1 null 1 Programming # id parent sort name
2 1 1 OOP
3 2 1 PHP
4 2 1 Ruby
5 1 2 Functional
I'm creating a website which has posts and a commenting section. I'm very interested in "Lower bound of Wilson score confidence interval for a Bernoulli parameter" sorting algorithm which is explained by Evan Miller here.
And, my comment system has nested comments. How I store the comments in the postscomments table in MYSQL is as follows.
Id | ParentId | Comment | PostId | ...
1 NULL Parent Comment 1
2 1 Child comment 1
3 2 Grand Child comment 1
Inserting, updating, and deleting just work as a piece of cake.
Selecting is the worst thing. Let me tell you how I need it to be selected.
When I receive an AJAX request for my get-comments.php file, I need to get the comments for a specific post. (AJAX request sends the post ID). So, I need to select the comments of that post sorted according to that algorithm.
But, the problem is that I only need to select 30 parent comments, and 5 child comments per each parent. I'm not sure about a way to do the sorting and grouping at once in MYSQL query. Here's what I tried.
Recursive Query It didn't work for two reasons. I cannot group the results into parents and I cannot limit the resutls. (LIMIT is not supported inside WITH RECURSIVE)
Other hierarchical storage methods I tried some of them. But, they didn't work too.
So, finally I came up with SELECTING ALL and processing with PHP which succeeded 100%.
Here's the long PHP script that does the thing. It works very well. Returns grouped results, sorted correctly.
But, the problem I have is that, I have no comments limit per each post. So, If I get 100,000 or more comments per post, will my server get overloaded? There's not just 1 post, so I think this is not the best solution.
Do you have a better solution this?
Is there a way that I can do all of these things in a MYSQL query and reduce the number of rows that I select?
Thanks in advance.
Added:
Here's the structure of JSON Response that I need to get.
{
"parent": [
// sorted parent comments
{
"Id": 4,
"UserId": 2,
"PostId": 1,
// and other comment data
},
{
// another comment
}
],
"4": [
// sorted array of children of comment 4
{
// comment 4's child
},
{
// comment 4's child
}
],
"6": [
// sorted array of children of comment 6
]
}
Is there a way that I can first sort the comments on that algorithm, then select only the first 30 parent comments and only 5 child comments per each parent just using a MYSQL Query? (If I could do that, I can group that result to this JSON with PHP)
Everytime you are storing new vote, do:
Store sum of upvotes and downvotes on each comment (you can do just "current+=1") - you will get rid of the "LEFT JOIN postscommentsvotes"
Store the result of the crazy expression in ORDER BY into a column in the comments table as well. (lets call it Priority)
Separate the search query into two both using the precomputed Priority for sorting:
searches for parents with WHERE PostId = ? ORDER BY Priority DESC LIMIT 30. Compount key (PostId, Priority) may be useful.
query for all Id, ParentId WHERE PostId = ? ORDER BY ParentId, Id
construct a tree from the result and exclude branches not belonging under comments from first query.
query for children using ParentId IN (?) with parent ids being all ids of comments from given branch of the preconstructed id-tree (do this for each parent or compose a UNION)
Alternatively, query step 2 and process step 3 for each parent separately, but they may overlap, hard to say what will be better.
Btw, the first part may be optional, but since you split the search query in two both using the Priority, and potentialy both using it on the same rows, it also fastens up because you only compute it once for each upvote/downvote, instead of once or twice for each post detail request.
I have a list of products, which can have different properties (color, size etc).
Properties are saved in my db as property table in the following form:
While the chosen properties get saved to each individual product in the form of parentid.id, for example this 2nd entry (id 4) has blue color property.
But what I'm trying to achieve now, is to echo these selected values on the product, the same way they are saved, so:
Parent Title - This id (child) or based on example: Color - Blue.
But I can't figure out, how to. I've tried imploding the properties array, but then I only get the last part, so only 2 from 1.2 and echoes Blue. I would need both, 1 and 2 (Color-blue).
It's kind of hard to explain, but if anyone understood at least a bit what I would need and has any idea how this could be done, I would be very grateful for any tips and hints.
Thanks in advance ;)
What you need to do to make this work:
Select your properties from db
Parse them into groups (explode by ',' to work with them one at a time)
Build an array of parent/children by parsing the groups
(ex: groupings = [
parent1 => [child1, child2, etc],
parent2 => [child1, child2, etc],
])
a. loop through each group
b. explode by '.' to get the parent/child pairing
c. put into array
Build your where clause
a. Parents: where (id in (parent1, parent2, etc))
b. Children: (parent = parent AND id IN (child1, child2, etc))
This is my database structure:
I would like to loop through all the child elements (those who's parent_id is set to the data_id within the same table).
Therefore those with "parent_id" as "0" are parents, and those with parent_id with a number in it is a child.
I would like help creating a function that will generate tables, with the table itself as the parent, and all the rows within it would be children of that parent. There is only one layer of depth in this project (one parent and one child layer always. ).
Can anyone help, or would want a more detailed description?
Thank you, and looking forward to a reply.
From my perspective, as when I look at your database, I assume that your parent will always be added before your child is (If I am wrong, please correct me). And because you said that you only have 1 parent and 1 child, I believe this is how your database would look like:
1st - parent
2nd - child of 1st
3rd - parent
4th - child of 3rd
If that's the case, one single loop can help you out with this pseudo code
//get the data from the database
//run through the loop
//check if the parent_id is 0
// if it is, create an element (a table) to be the container with the id as cited in your data_id
// if is is not, create an element (a row). Then append this element to the table with the same id as this parent_id