2

Here is my scenario:

Database Name: Children
+-------------+---------+---------+
| child_id   | name      | user_id |
+-------------+---------+---------+

    1           Beyonce     33
    2           Cher        33
    3           Madonna     33
    4           Eminem      33


Database Name: Parents
+-------------+---------+---------+
| parent_id   | child_id   | parent_name |
+-------------+---------+---------+

    1           1           Obama
    2           1           Michelle
    3           4           50cents
    4           4           Gaga


Desired Output:
+-------------+---------+---------+
| child_id   | name      | parent Name |
+-------------+---------+---------+
    1           Beyonce     Obama (Row 1) Michelle (Row 2)

PHP SQL Query in PDO:

$sql = "SELECT  Children.child_id, Children.name, Parents.parent_name
        FROM Children               
        LEFT JOIN Parents
            ON Children.child_id = Parents.child_id
        WHERE Children.user_id = ?
        ";

$stmt = $db_PDO->prepare($sql); 

if($stmt->execute(array($userId))) // $userId defined earlier
{
        // Loop through the returned results
        $i = 0;

        foreach ($stmt as $row) {
            $fetchArray[$i] = array (
                'childId' => $row['child_id'],
                'childName' => $row['name'],    
                'parentName' => $row['parent_name'],    
                // How do I save the multiple parents from other rows here ????
                );                  
            $i++;
        }             
}

How can I run a query that Joins 1 row to multiple rows in second table in PDO? I have read other topics here but I am unsure. Is it easier to add a second query that gets the linked parents for each child_id separately in a loop? I am worried that will be too much query. Can someone help me solve this?

Neel
  • 9,352
  • 23
  • 87
  • 128
  • http://stackoverflow.com/questions/2577174/join-vs-sub-query – ashkufaraz Apr 05 '15 at 17:39
  • Good link. But I was wondering if its possible to do my scenario in `SQL Joins` so it can be done in 1 query instead of multiple sub-queries? Sub-queries can soon accumulate to be too much in big lists. – Neel Apr 05 '15 at 17:42
  • If sub-query is my only option, can someone give me an example in my scenario please? – Neel Apr 06 '15 at 08:36
  • Can you provide a set up sql fiddle with dummy data and tables structure you'd like. I might know a few tricks that could help you. – Tschallacka Apr 08 '15 at 07:04
  • Hi @MichaelDibbets I havent done sql fiddle before. Plz give me a moment and I will try to sent one up. :) – Neel Apr 08 '15 at 07:18
  • Hi @MichaelDibbets Here is the SQL Fiddle I have created for this: http://sqlfiddle.com/#!9/64c05/1 I am trying to achieve 2 things here: (1) Get the SQL Output in pdo using prepare statement and (2) store these values in `$fetchArray[$i]` where I dont know how many parent_name values will each child_id row output will have like its shown in my second half of my example in my post above. – Neel Apr 08 '15 at 07:33

3 Answers3

1

Execute the below query . You will get the output as required, i just used the group by which will group the records as per the selected column

select a.child_id, name ,group_concat(parent_name) from children a, parents b where a.child_id =b.child_id group by a.child_id

Swetha reddy
  • 61
  • 1
  • 12
  • Thank you Swetha. Michael's answer was using the `group_concat` too like you said and using php to sort out the array in the end. I appreciate your answer too. :) – Neel Apr 08 '15 at 09:13
1

Well, took me some fiddling to test it all out but here you go. Unfortunately one cannot easely pivot tables in mysql but there are alternatives.

http://sqlfiddle.com/#!9/1228f/26

SELECT GROUP_CONCAT(
  CONCAT_WS(':', Parents.parent_id,Parents.parent_name) ) FROM Parents where Parents.child_id=1

;
SELECT
  Children.child_id,
  Children.name,
  GROUP_CONCAT(
  CONCAT_WS(':', Parents.parent_id,Parents.parent_name)    ) as parents
FROM
  Children
  LEFT JOIN Parents
        ON Children.child_id = Parents.child_id
        WHERE Children.user_id = 33
  Group by Children.child_id

This query uses the group concat to concatenate all resulsts we want into a colon seperated string with the values we want, and comma's between the individual fields.

We could do some tricky magic to make them individual fields but that would break our php because we wouldnt know how much fields each query would return(adopted, orphan, no known parents, etc...)

In php you could feed them into an object

$parents = array();
$loop1 = explode(',',$row['parents']);
    foreach($loop1 as $parentset) {
        $parentdetail = explode(":",$parentset);// decide yourself how much detail you want in here... I jsut went with name and id.
        $parent = new stdClass();
        $parent->id = $parentdetail[0];
        $parent->name = $parentdetail[1];
        array_push($parents,$parent);
    }

var_dump($parents);
Tschallacka
  • 27,901
  • 14
  • 88
  • 133
  • Wow.. That is just brilliant. Using `GROUP_CONCAT` for SQL and then `explode()` and add to an array in php. That is very good. It seemed hard at first but after re-reading it and playing with your sqlfiddle, I love how you did it. Thank you @MichaelDibbets. I was stuck on this for awhile! Looking forward to put this into my code. :) – Neel Apr 08 '15 at 09:11
  • I can award my bounty in 21 hours. :) – Neel Apr 08 '15 at 09:12
  • 1
    Depending on your code format end endresult there might be more efficient ways than explode, but i went for the quick and dirty way that gave immedeate results. it's up to you to decide the memory effiency and speed. – Tschallacka Apr 08 '15 at 09:22
  • Hi Michael, I tried adding this sql solution in my application and I just now realised that my application structure is slightly different from my example above. I actually have 3 tables (1) Children Table (2) Parent Table and (3) Parent-Child Relation Table. So I actually need to Left join 2 times to get to the parent name. I have put together a code based on your example and got it working. Although its working, can you take a quick look at this SQL Fiddle and tell me if I got it right please? Its like before but parent child relation is in a separate table. http://sqlfiddle.com/#!9/fd0c5/1 – Neel Apr 08 '15 at 20:30
  • 1
    Yea its proper. No subqueries etc, and an extra join doesnt impact the speed. But keep in mind that any string operation is alwaus expensive. So try to keep the concatted data to a minimum or even consider making a seperate table with the data that updates on trigger. – Tschallacka Apr 08 '15 at 20:39
  • 1
    Thank you so much Michael. You've been so kind and helpful :) – Neel Apr 08 '15 at 20:43
0

HI this query works only if you are passing child id ,

select a.child_id, name ,group_concat(parent_name ) parent_name from children a, parents b where a.child_id =b.child_id and a.child_id=1

here i am using a function called group_concat which is used for concatinating the rows.It automatically takes the rows whose count is greater than 1.So no need of the extra code again

Swetha reddy
  • 61
  • 1
  • 12
  • Thank you @Swethareddy for that. Since I wont know the `child_id` first, I guess in this method I might need to add this as a sub-query after first fetching the child_id's first. I am just worried if this will become like tangled queries with too much overload in long lists of child_id's. – Neel Apr 08 '15 at 07:42