简体   繁体   中英

Left Join multiple times 2 tables using same column ON

I have a table A where several columns values should be replaced from corresponding id which are stored in table B as in this scheme:

TABLE_A
object_id   desc_id_1   desc_id_2   desc_id_3   desc_id_4   
zxy_34      9999        9567        5555        5556

TABLE_B
desc_id   complete_desc
1234      ABCD
9999      ZYXW
9567      POTG
5555      YUNR
5556      LPVR 
……..
……..

Final show than should be like that:

object    comp_desc_1  comp_desc_2  comp_desc_3  comp_desc_4
zxy_34    ZYXW         POTG         YUNR         LPVR

Is it possible?

At the moment tried something like that:

$sql="SELECT table_a.object_id, table_b.complete_desc 
FROM table_a 
LEFT JOIN table_b ON table_a.desc_id_1 =table_b.complete_desc";

It works ok using output this way:

echo "<table border='1'>
<tr>
<th>object</th>
<th>comp_desc_1 </th>
</tr>";

while($row = mysqli_fetch_array($result)) {
                                                echo "<tr>";
    echo "<td>" . $row['object_id '] . "</td>";
    echo "<td>" . $row['desc_id_1 '] . "</td>";
    echo "</tr>";
                                                }
echo "</table>";

The problem is that don't really know how to go further. Adding another left join like that stop the script and make load a blank page:

$sql="SELECT table_a.object_id, table_b.complete_desc, table_b.complete_desc 
FROM table_a 
LEFT JOIN table_b ON table_a.desc_id_1 =table_b.complete_desc
LEFT JOIN table_b ON table_a.desc_id_2 =table_b.complete_desc ";

…..

echo "<table border='1'>
<tr>
<th>object</th>
<th>comp_desc_1 </th>
<th>comp_desc_2 </th>
</tr>";

while($row = mysqli_fetch_array($result)) {
                                                echo "<tr>";
    echo "<td>" . $row['object_id '] . "</td>";
    echo "<td>" . $row['desc_id_1 '] . "</td>";
    echo "<td>" . $row['desc_id_2'] . "</td>";
    echo "</tr>";
                                                }
echo "</table>";

Some one can help me?

You need to give each instance of table_b in your query an alias, otherwise it can't be known which one you are referring to. You also need to give the separate complete_desc values different names so they don't overwrite each other in the output array. Try something like this:

$sql="SELECT table_a.object_id, b1.complete_desc AS desc_id_1, b2.complete_desc AS desc_id_2
FROM table_a 
LEFT JOIN table_b b1 ON table_a.desc_id_1 = b1.complete_desc
LEFT JOIN table_b b2 ON table_a.desc_id_2 = b2.complete_desc ";

You also need to remove the spaces in the array keys in these lines:

echo "<td>" . $row['object_id '] . "</td>";
echo "<td>" . $row['desc_id_1 '] . "</td>";

they should be:

echo "<td>" . $row['object_id'] . "</td>";
echo "<td>" . $row['desc_id_1'] . "</td>";

To get what you want, the JOINs need to be on the matching IDs, then get the respective description AFTER the join. If a given "ID" may not be present, you would need a LEFT-JOIN meaning all records from the LEFT side (first table/alias) regardless of a match on the right (second table/alias). Also, good to get into using aliases to simplify readability, especially on long table names, or when you need the same table multiple times such as this case...

select
      a.Object_ID,
      id1.complete_desc ID1Descript,
      id2.complete_desc ID2Descript,
      id3.complete_desc ID3Descript,
      id4.complete_desc ID4Descript
   from
      Table_A  a
         LEFT JOIN Table_B id1
            on a.desc_id_1 = id1.desc_id
         LEFT JOIN Table_B id2
            on a.desc_id_2 = id2.desc_id
         LEFT JOIN Table_B id3
            on a.desc_id_3 = id3.desc_id
         LEFT JOIN Table_B id4
            on a.desc_id_4 = id4.desc_id

Your join would never have a match such as ID Number compared to a description. You need the ID from the columns in your Table_A joined to the ID column of TableB, hence multiple "alias" references for alias "id1", "id2", "id3", "id4"...

BTW, may people frown on too many underscores for tables and/or columns. Get used to CamelCaseColumnNaming vs Using_Underscore_For_Columns. Just a suggestion...

It is important that I urge you to restructure your "table_a" table. It just isn't set up to run clean, efficient, concise queries.

To normalize the structure, I recommend these columns:

object_id
desc_id
desc_order

Then the "pivot" query that you desire can be executed with just one LEFT JOIN.

SELECT object_id,
       MAX(CASE WHEN desc_order = 1 THEN b.desc_id ELSE NULL END) AS desc_id1, 
       MAX(CASE WHEN desc_order = 2 THEN b.desc_id ELSE NULL END) AS desc_id2, 
       MAX(CASE WHEN desc_order = 3 THEN b.desc_id ELSE NULL END) AS desc_id3, 
       MAX(CASE WHEN desc_order = 4 THEN b.desc_id ELSE NULL END) AS desc_id4
FROM `table_a` a
LEFT JOIN `table_b` b ON a.desc_id = b.desc_id
GROUP BY `object_id`

SQLFIDDLE DEMO

I can only hope that you aren't too far in your project to make this adjustment, because it will set you up for a much easier time developing in the future. (Plus flexibility is improved -- if you decide you want more than 4 columns, you can seamlessly include 5 or more columns in the result set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM