当前位置:首页 > 问答 > 正文

PHP里数据库JOIN到底咋用,初学者也能看懂的简单讲解

PHP里说到数据库JOIN,其实你不用把它想得太复杂,你就把它当成一个“牵线搭桥”的过程,想象一下,你手头有两张表格:一张是“学生名单”,另一张是“班级信息”。

“学生名单”表格(students)里可能有这些列: | id | student_name | class_id | |----|-------------|----------| | 1 | 张三 | 101 | | 2 | 李四 | 102 | | 3 | 王五 | 101 |

“班级信息”表格(classes)里是这样的: | class_id | class_name | |----------|------------| | 101 | 高一(1)班 | | 102 | 高一(2)班 |

你想得到一个结果,里面能看到每个学生的名字和他们所在的班级名字,而不是那个冷冰冰的数字class_id,该怎么做呢?你不可能手动去一个个对照,因为数据多了会累死,这时候,JOIN就派上用场了。

JOIN的作用,就是根据两个表格都有的那个“桥梁”字段(在这里就是class_id),把这两张表的数据合并到一张结果表里给你看。

在PHP中,我们通常先用PDO或MySQLi扩展连接数据库,然后写SQL查询语句,JOIN就是这个语句的一部分,下面我用PDO的方式,结合最常见的几种JOIN来给你讲明白。

INNER JOIN(内连接):最常用的“找共同”

它的逻辑很简单:只返回两个表中能匹配上的记录

继续用上面的例子,我们想找学生和其班级的对应关系,SQL语句这么写:

<?php
// ... 假设你已经建立了PDO连接,叫 $pdo
$sql = "
    SELECT students.student_name, classes.class_name
    FROM students
    INNER JOIN classes ON students.class_id = classes.class_id
";
$stmt = $pdo->query($sql);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 打印结果
foreach($results as $row) {
    echo $row['student_name'] . " 在 " . $row['class_name'] . " 学习。<br>";
}
?>

这段代码运行后,你会得到:

张三 在 高一(1)班 学习。
李四 在 高一(2)班 学习。
王五 在 高一(1)班 学习。

你看,INNER JOIN就像一次“精准匹配”,它拿着students表的每一个class_id,去classes表里找相同的class_id,找到了就把这两行信息拼在一起返回,如果有个学生class_id是999(班级表里没有),或者班级表里有个103班(没有学生),这些“落单”的记录是不会出现在结果里的。

LEFT JOIN(左连接):“以我为主”

LEFT JOIN的意思是:返回左表(JOIN关键字左边的表)的所有记录,即使右表没有匹配上,如果右表没匹配上,结果中右表的部分就显示为NULL

假设我们新增一个学生“赵六”,他刚转来还没分班,所以他的class_id是NULL。

id student_name class_id
4 赵六 NULL

现在我们把上面的SQL语句中的INNER JOIN改成LEFT JOIN

$sql = "
    SELECT students.student_name, classes.class_name
    FROM students
    LEFT JOIN classes ON students.class_id = classes.class_id
";

这次的结果会是:

张三 在 高一(1)班 学习。
李四 在 高一(2)班 学习。
王五 在 高一(1)班 学习。
赵六 在  学习。 // 注意,这里class_name是NULL,所以是空的

LEFT JOIN保证了“学生名单”(左表)里的所有学生一个不落都会出现,不管他有没有分班,对于赵六,因为他在班级表里找不到对应的记录,所以班级名字那块就是空的,这在统计“哪些学生还没分班”的时候特别有用。

RIGHT JOIN(右连接):“以他为主”

RIGHT JOIN和LEFT JOIN正好相反:返回右表(JOIN关键字右边的表)的所有记录,即使左表没有匹配上,如果左表没匹配上,结果中左表的部分就显示为NULL

假设班级表新开了一个“高一(3)班”,但还没有学生加入。

class_id class_name
103 高一(3)班

我们把SQL改成RIGHT JOIN

$sql = "
    SELECT students.student_name, classes.class_name
    FROM students
    RIGHT JOIN classes ON students.class_id = classes.class_id
";

结果会是这样:

张三 在 高一(1)班 学习。
李四 在 高一(2)班 学习。
王五 在 高一(1)班 学习。
     高一(3)班  // 注意,这里student_name是NULL,所以是空的

这次,RIGHT JOIN保证了“班级信息表”(右表)里的所有班级都会出现,哪怕这个班一个学生都没有,这在统计“哪些班级还是空班”的时候很方便。

在PHP里用JOIN的核心步骤:

  1. 连接数据库:用PDO或MySQLi。
  2. 写SQL语句:这是关键,想清楚你要什么:
    • 只要两边都有的?用 INNER JOIN
    • 要左边全部,不管右边有没有?用 LEFT JOIN
    • 要右边全部,不管左边有没有?用 RIGHT JOIN
    • (还有一种FULL JOIN,两边全部都要,但MySQL不直接支持,这里不提)
  3. 指定连接条件ON table1.共同字段 = table2.共同字段,这是“桥”的两端。
  4. 执行查询并处理结果:和在PHP里执行普通SELECT查询一模一样。

最后记住,JOIN是SQL语言的功能,不是PHP的,PHP只是负责把这个SQL命令发送给数据库,然后把数据库返回的结果展示出来,你只要把JOIN的逻辑想成是“表格拼图”,根据不同的需求(要不要所有数据)选择不同的拼法(INNER, LEFT, RIGHT),就一点儿也不难了,多写几个例子试试,马上就懂了。

PHP里数据库JOIN到底咋用,初学者也能看懂的简单讲解