左联接多次使用同一列ON

时间:2018-11-06 00:19:47

标签: php sql left-join

我有一个表A,其中应该从相应的ID替换几列值,这些ID是以这种方式存储在表B中的:

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 
……..
……..

最后的演出应该是这样的:

object    comp_desc_1  comp_desc_2  comp_desc_3  comp_desc_4
zxy_34    ZYXW         POTG         YUNR         LPVR

有可能吗?

此刻尝试过类似的事情:

$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";

以这种方式使用输出可以正常工作:

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>";

问题是,您真的不知道该怎么做。 像这样添加另一个左连接,停止脚本并加载空白页面:

$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>";

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:1)

您需要为查询中的每个table_b实例指定一个别名,否则就无法知道您指的是哪个实例。您还需要给单独的complete_desc值指定不同的名称,以免它们在输出数组中彼此覆盖。尝试这样的事情:

$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 ";

您还需要在以下几行中删除数组键中的空格:

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

它们应该是:

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

答案 1 :(得分:0)

要获得所需的内容,JOIN必须位于匹配的ID上,然后在联接之后获取相应的描述。如果给定的“ ID”可能不存在,则需要LEFT-JOIN,这意味着来自LEFT端(第一张表/别名)的所有记录,无论右侧是否匹配(第二张表/别名)。另外,最好使用别名来简化可读性,特别是在长表名上,或者在这种情况下需要多次使用同一张表的情况下。

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

与描述相比,您的联接将永远不会有匹配项(例如ID号)。您需要将Table_A列中的ID加入到TableB的ID列中,因此别名“ id1”,“ id2”,“ id3”,“ id4” ...的多个“别名”引用...

顺便说一句,也许人们对表和/或列的下划线太多了。习惯使用CamelCaseColumnNaming和Using_Underscore_For_Columns。只是一个建议...

答案 2 :(得分:0)

重要的是,我敦促您重组您的“ table_a”表。只是没有将其设置为运行干净,高效,简洁的查询。

为使结构规范化,我建议以下列:

object_id
desc_id
desc_order

然后只需一个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

我只能希望您在项目中不会做太多调整,因为这将使您为将来的开发工作轻松得多。 (此外,灵活性也得到了提高-如果您决定要多于4列,则可以在结果集中无缝包含5列或更多列。