Welcome Guest, Not a member yet? Register   Sign In
Issue with Join and multiple rows
#1

[eluser]daparky[/eluser]
Hi everyone,

I have a slight issue joining multiple tables and getting multiple rows from those table into an array or object.

Basically i have 5 tables that all need to be joined together. It looks something like this:-

table1
-table1_id
-table1_name

table2
-table2_id
-table2_name
-t2_table1_id

table3
-table3_id
-table3_name
-t3_table1_id

table4
-table4_id
-table4_name
-t4_table1_id

table5
-table5_id
-table5_name
-t5_table1_id

Lets say table 4 has multiple rows for the same id in table1. At the moment my output looks like this:-

Code:
Array
(
    [0] => stdClass Object
        (
            [table1_id] => an id
            [table1_name] => a name
            [table2_name] => a name
            [table3_name] => a name
            [table5_name] => a name
            [table4_name] => a name
        )

)

Table4 has multi rows with the same table1_id so i want them included into the array like this:-

Code:
Array
(
    [0] => stdClass Object
        (
            [table1_id] => an id
            [table1_name] => a name
            [table2_name] => a name
            [table3_name] => a name
            [table5_name] => a name
            [table4_name] => Array
                (
                    [0] => stdClass Object
                        (
                            [table4_name] => a name
                           )

                    [1] => stdClass Object
                        (
                            [table4_name] => a name
                           )

                )
        )

)

Here's my AR query:-

Code:
$this->db->select('*');
        $this->db->join('table2', 'table1_id = t2_table1_id', 'left');
        $this->db->join('table3', 'table1_id = t3_table1_id', 'left');
        $this->db->join('table5', 'table1_id = t5_table1_id', 'left');
        $this->db->join('table4', 'table1_id = t4_table1_id', 'left');

$this->db->group_by('table1');
return $this->db->get('table1')->result();

It's returning the results properly it just doesn't get multi values from table 4 if there are any, it seems to only return the first row it finds.

Any help would be appreciated.
#2

[eluser]vitoco[/eluser]
group_by COLUMN, returns only one row per value of the column. removing the group by will get you all rows from table4..
#3

[eluser]daparky[/eluser]
I tried removing group by and the results duplicated to how many rows I had in table 4. The results look like this after removing group by:-
Code:
Array
(
    [0] => stdClass Object
        (
            [table1_id] => an id
            [table1_name] => a name
            [table2_name] => a name
            [table3_name] => a name
            [table5_name] => a name
            [table4_name] => a name
        )

    [1] => stdClass Object
        (
            [table1_id] => an id
            [table1_name] => a name
            [table2_name] => a name
            [table3_name] => a name
            [table5_name] => a name
            [table4_name] => a name2
        )

    [2] => stdClass Object
        (
            [table1_id] => an id
            [table1_name] => a name
            [table2_name] => a name
            [table3_name] => a name
            [table5_name] => a name
            [table4_name] => a name3
        )
)
The results need to be like those demonstrated in the first post.
#4

[eluser]WanWizard[/eluser]
You can't do that with a single query.

You're trying to convert a flat structure (table of rows) into a hierarchical structure. You will have to do that in code, i.e. loop through the result, and collapsing it while you loop...
#5

[eluser]daparky[/eluser]
[quote author="WanWizard" date="1277925605"]You can't do that with a single query.

You're trying to convert a flat structure (table of rows) into a hierarchical structure. You will have to do that in code, i.e. loop through the result, and collapsing it while you loop...[/quote]

Thanks alot WanWizard for pointing me in the right directing. Do you have any example code you could show me i could maybe base this off.

Also, will this take a hit on performance looping through the query etc? Are there any other ways of doing it, e.g. sub query?
#6

[eluser]WanWizard[/eluser]
Maybe it's better if you try to explain what you intend to do with such a structure, because it seems to me that it is quite complicated to parse.

why not:
Code:
Array
(
    [0] => stdClass Object
        (
            [table1_id] => an id
            [table1_name] => a name
            [table2_name] => a name
            [table3_name] => a name
            [table5_name] => a name
            [table4_name] => Array
                (
                    [0] => a name
                    [1] => a name2
                    [2] => a name3
                )
        )
)
#7

[eluser]WanWizard[/eluser]
You might be able to do something like
Code:
$this->db->select('table1.*, GROUP_CONCAT(DISTINCT table1_name), GROUP_CONCAT(DISTINCT table2_name), GROUP_CONCAT(DISTINCT table3_name), GROUP_CONCAT(DISTINCT table5_name), GROUP_CONCAT(DISTINCT table4_name)', FALSE);
        $this->db->join('table2', 'table1_id = t2_table1_id', 'left');
        $this->db->join('table3', 'table1_id = t3_table1_id', 'left');
        $this->db->join('table5', 'table1_id = t5_table1_id', 'left');
        $this->db->join('table4', 'table1_id = t4_table1_id', 'left');

$this->db->group_by('table1');
return $this->db->get('table1')->result();
#8

[eluser]daparky[/eluser]
[quote author="WanWizard" date="1277932335"]You might be able to do something like
Code:
$this->db->select('table1.*, GROUP_CONCAT(DISTINCT table1_name), GROUP_CONCAT(DISTINCT table2_name), GROUP_CONCAT(DISTINCT table3_name), GROUP_CONCAT(DISTINCT table5_name), GROUP_CONCAT(DISTINCT table4_name)', FALSE);
        $this->db->join('table2', 'table1_id = t2_table1_id', 'left');
        $this->db->join('table3', 'table1_id = t3_table1_id', 'left');
        $this->db->join('table5', 'table1_id = t5_table1_id', 'left');
        $this->db->join('table4', 'table1_id = t4_table1_id', 'left');

$this->db->group_by('table1');
return $this->db->get('table1')->result();
[/quote]

WanWizard, this query worked to a certain degree, it output this:-

Code:
Array
(
    [0] => stdClass Object
        (
            [table1_id] => an id
            [table1_name] => a name
            [GROUP_CONCAT(DISTINCT table2_name)] => a name2
            [GROUP_CONCAT(DISTINCT table3_name)] => a name3
            [GROUP_CONCAT(DISTINCT table5_name)] => a name5
            [GROUP_CONCAT(DISTINCT table4_name)] => aname1,aname2,aname3
        )
)

Ideally i would like results to appear like you said:-

Code:
Array
(
    [0] => stdClass Object
        (
            [table1_id] => an id
            [table1_name] => a name
            [table2_name] => a name
            [table3_name] => a name
            [table5_name] => a name
            [table4_name] => Array
                (
                    [0] => a name
                    [1] => a name2
                    [2] => a name3
                )
        )
)

Getting very close to solving this issue Smile
#9

[eluser]vitoco[/eluser]
if you apply explode in the loop to
Code:
$row['GROUP_CONCAT(DISTINCT table4_name)'] = explode(',' , $row['GROUP_CONCAT(DISTINCT table4_name)']);

you'll get and array of table4_nameS.

Also try to add some alias to every GROUP_CONCAT statement like
Code:
$this->db->select('table1.*, GROUP_CONCAT(DISTINCT table1_name) AS table1_name ...');
it gets easier to read and process


Saludos




Theme © iAndrew 2016 - Forum software by © MyBB