获取与其ID

时间:2017-04-15 22:07:35

标签: php

问题

所以,我不知道如何才能做到这一点,但我想做的是获得领导者的名字和姓氏以及学生使用他们的身份证明。在我得到学生和领导者的名字和姓氏后,我需要输出它。

小组表

id | leaderID | studentID
1  | 123      | 123456
2  | 123      | 09
3  | 123      | 7776
4  | 233      | 80
5  | 233      | 997

学生表

studentID | firstname | lastname | teacherID
----------|-----------|----------|----------
123       | Dave      | Jackson  | 23
123456    | Jessie    | Roberts  | 23
09        | Rick      | Rustels  | 24
7776      | Blake     | Jackson  | 25
80        | Ashly     | Kenson   | 23
233       | Lilly     | Street   | 25
997       | Billy     | Street   | 24

我目前正在获取的内容(第一个ID是领导者的ID)

123
123456
09
7776

233
80
997

我想要什么

Dave Jackson
Jessie Roberts
Rick Rustels
Blake Jackson

Lilly Street
Ashly Kenson
Billy Street

所以基本上我想得到与他们的ID相对应的名字和姓氏。

PHP代码

<?php 

require '../connect.php';

$team_data = $link->prepare("SELECT leaderID, studentID, CONCAT(firstname, ' ', lastname) as firstlast FROM teams, students Order by leaderID, studentID");
$team_data->execute();
$team_data = $team_data->fetchAll();

if(!$team_data) {
    header("Location: ../../admin.php?msg=Sorry we could not get the data");
}

$data = [];

foreach ($team['firstlast'] as $team) {
    $leader_id = $team['leaderID'];
    $student_id = $team['studentID'];
    $data[$leader_id][] = $student_id;
}

?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Teams</title>
</head>
<body>

    <?php foreach ($data as $leader_id => $students): ?>
        <ul>
            <li><strong><?php echo $leader_id; ?></strong></li>
                <?php foreach ($students as $student_id): ?>
            <li><?php echo $student_id; ?></li>
                <?php endforeach; ?>
        </ul>
    <?php endforeach; ?>

</body>
</html>

3 个答案:

答案 0 :(得分:7)

单个查询

(
  SELECT 1 AS leader, s.studentID AS leaderID, s.studentID,
    s.firstname, s.lastname
  FROM teams AS t
  JOIN students AS s ON s.studentID = t.leaderID
  GROUP BY t.leaderID
) UNION (
  SELECT 0 AS leader, t.leaderID, s.studentID, s.firstname, s.lastname
  FROM teams AS t
  JOIN students AS s ON s.studentID = t.studentID
) ORDER BY 2, 1 DESC;

该查询由两个SELECTUNION组成。第一个选择仅使用GROUP BY删除重复项的领导者。第二个子查询选择其余学生。最后,结果集按引导ID按升序排序,按leader标志按降序排序。

示例输出

leader leaderID studentID firstname lastname
1      123      123       Dave      Jackson
0      123      9         Rick      Rustels
0      123      7776      Blake     Jackson
0      123      123456    Jessie    Roberts
1      233      233       Lilly     Street
0      233      80        Ashly     Kenson
0      233      997       Billy     Street

注意,您可能需要优化表结构才能运行此查询而不会降低性能。例如,您可能需要为leaderIDstudentID列添加索引。

两个查询+ PHP

通常,一些简单查询比单个复杂查询更快。此外,在某些情况下,在PHP中而不是在SQL中实现排序和分组操作时会更快。以下是另一种可能比上述复杂查询运行得更快的方法。制定一些基准测试,以找出哪种更适合您的情况。

<?php
$result = [];

// Collect only leaders
$q = 'SELECT s.studentID, s.firstname, s.lastname
    FROM students AS s, teams AS t
    WHERE t.leaderID = s.studentID
    GROUP BY 1';
$cursor = Db::query($q);
while ($row = Db::fetchNext($cursor)) {
    $result[$row['studentID']][] = $row;
}
$cursor->free();

// Collect the rest
$q = 'SELECT s.studentID, t.leaderID, s.firstname, s.lastname
    FROM students AS s, teams AS t
    WHERE t.studentID = s.studentID';
$cursor = Db::query($q);
while ($row = Db::fetchNext($cursor)) {
    $leader_id = $row['leaderID'];
    if (isset($result[$leader_id])) {
        $result[$leader_id][] = $row;
    }
}
$cursor->free();

第一个区块仅选择领导者,并通过$result密钥将其存储到studentID

如果存在相应的$result,则第二个区块会收集其余学生,并以类似的方式将其存储到leaderID。 (您可以通过WHERE将引导ID传递给IN()子句来跳过此检查。)

由于$result最初是由领导者填补的,所以领导者将被存储在第一个位置:

Array
(
    [123] => Array
        (
            [0] => Array
                (
                    [studentID] => 123
                    [firstname] => Dave
                    [lastname] => Jackson
                )

            [1] => Array
                (
                    [studentID] => 123456
                    [leaderID] => 123
                    [firstname] => Jessie
                    [lastname] => Roberts
                )
                (skipped...)
        )

    [233] => Array
        (
            [0] => Array
                (
                    [studentID] => 233
                    [firstname] => Lilly
                    [lastname] => Street
                )
                (skipped...)
        )
)

Db::query()Db::fetchNext()是虚函数。前者对数据库执行SQL查询并将游标返回到结果集。后者使用游标获取下一个结果。

答案 1 :(得分:0)

使用sql:CONCAT(firstname, ' ', lastname)

变化:

$team_data = $link->prepare("SELECT leaderID, studentID FROM teams order by leaderID, studentID");

要:

$team_data = $link->prepare("SELECT leaderID, studentID, CONCAT(firstname, ' ', lastname) as firstlast FROM teams, students Order by leaderID, studentID");

然后在foreach内,您可以使用$team['firstlast']

答案 2 :(得分:0)

由于您在学生表中找到了您的姓/名,因此您需要加入该表。所以你的查询应该成为:

$team_data = $link->prepare("SELECT a.leaderID, a.studentID, CONCAT(b.firstname, ' ', b.lastname) AS full_name FROM teams AS a LEFT JOIN stundent_table AS b ON a.studentID = b.studentID ORDER BY a.leaderID, a.studentID");

您的学生表名称是什么。相应地改变。