水平和动态地联接表

时间:2019-07-05 21:39:08

标签: php mysql

需要水平连接表的帮助

+---------+---------+
| Candidates Table  |
+---------+---------+
| can_id   | Name   | 
+---------+---------+
| 1       | Liza    |
| 2       | Sarah   |
| 3       | Jane    |
|         |         |
+---------+---------+

+---------+---------+
| Judges Table      |
+---------+---------+
| id      | Name    | 
+---------+---------+
| 1       | judge1  |
| 2       | judge2  |
| 3       | judge3  |
+-------------------+

+---------+---------------+--------+-------+
|                Score Table               |
+---------+-------+------------------------|
| sco_id  |  can_id| jud_id |crit_id |score|
+---------+--------+-----------------------+
| 1       |   1    |   2    |    1   |  87 |
| 2       |   1    |   3    |    1   |  89 |
| 3       |   1    |   1    |    1   |  80 |
+------------------------------------------+

I need an output of something like this one..

+---------+---------------+-------------+
|                Score board            |
+---------+---------+-------------------|
| Name    |  judge1 | judge2  | judge3  |
+---------+---------+-------------------|
| Liza    |   80    |    87   |    89   |  
|some data|some data|some data|some data|  
|some data|some data|some data|some data|  
+---------------------------------------+

注释:crit_id是标准表中的标准ID。

通常我会使用一些联接和子查询,但是我的问题是我需要动态输出,如果我添加新的评委,它将自动生成一个新列。.我需要至少1个具有所有评委分数的候选数据只需在php上使用参数循环它即可获取其他应聘者数据,例如

php loop start
   <td>name</td> 
   <td>judge1 score</td>
   <td>judge2 score</td> 
php end loop

或者如果我能得到整个候选人表,而法官的分数对我来说要好得多,不要让每个候选人都将其圈出来

我试图研究类似的问题

Concatenate more than two tables horizontally in SQL Server

我试图为自己编码,但我仍然无法加入评委。

SELECT s.sco_id,c.Name,c.Municipalities FROM `tbl_scoring` s left join tbl_candidates c on c.`can_id` = s.`can_id` where s.can_id = 11 and crit_id =1 order by s.jud_id asc

我需要一个查询,该查询将根据法官人数动态生成,或者获取具有法官分数的候选数据,然后在php上循环它;如果我获取所有数据而没有循环,则该方法要好得多

2 个答案:

答案 0 :(得分:1)

初始化以下数组:

$judges = [];
$scores = [];
$candidates = [];

然后执行查询,并循环结果。为每次迭代设置这些值:

$judges[$row['jud_id']] = 1;
$candidates[$row['can_id']] = $row['Name'];
$scores[$row['can_id']][$row['jud_id']] = $row['score'];

现在您想让参与者判断名字,所以让我们运行一个SQL查询:

$sql = 'SELECT Name FROM judges WHERE id IN (' . implode(',', array_keys($judges)) . ')';

然后在每次迭代中,在$judges数组中设置法官的姓名:

$judges[$row['id']] = $row['Name'];

然后输出:

echo '<tr>';
echo '<td>Name</td>';
ksort($judges);
foreach ($judges as $name) {
    echo '<td>Judge: ' . $name . '</td>';
}
echo '</tr>';

foreach ($scores as $candidateId => $data) {
    echo '<tr>';
    echo "<td>$candidates[$candidateId]</td>";
    ksort($data);
    foreach ($data as $score) {
        echo "<td>$score</td>";
    }
    echo '</tr>;
}

我在ksort$judges上使用了$data,因此分数适合每个法官。

答案 1 :(得分:1)

首先,我们获取分数表中存在的法官的ID和姓名。

$judges = [];
$query = "SELECT id, name FROM Judges WHERE id IN ( SELECT DISTINCT jud_id FROM Score )";
// execute the query and store the results in the $judges array.

我们检索分数表中存在的考生ID和姓名。

$candidates = [];
$query = "SELECT id FROM Candidate WHERE id IN ( SELECT DISTINCT can_id FROM Score )";
// execute the query and store the results in the $candidates array.

然后,我们将候选者和得分表连接起来。

$candidate_score = [];
$query = "SELECT Candidate.name, Candidate.id as candidate_id , Score.jud_id, Score.score FROM Candidate JOIN Score ON Score.can_id = Candidate.id";
// execute the query and store it in the $candidate_score array.

现在,对于每个候选人,我们将其得分填入$ score_board数组中。

$score_board = [];

foreach ( $candidates as $candidat )
{
   $score_board[$candidat] = [];

   foreach ( $judges as $judge )
   {
      $judge_name = $judge['name'];
      $judge_id = $judge['id'];
      $score_board[$candidat][$judge_name] = get_judge_score($candidate_score,$candidat,$judge_id);
   } 
}

get_judge_score的工作方式如下:

function get_judge_score ( $scores , $candidate , $judge )
{
   $score_filtred = array_filter($scores, function ($score) use ($candidate,$judge) {
      return $score['jud_id'] == $judge && $score['candidate_id'] = $candidate;
   });

   return count($score_filtred) > 0 ? $score_filtred[0]['score'] : 0;
}