【问题标题】:SQL/PHP: Joins with no matches on the other table (multiple tables)SQL/PHP:在另一个表(多个表)上没有匹配项的联接
【发布时间】:2019-05-29 21:45:31
【问题描述】:

我有四张桌子:

Personal_trainer(personaltrainerID, name, age, location)
Client(clientID, name, age, location)
Nutrition_Plan(NutritionplanID, personaltrainerID, clientID)
Training_Plan(TrainingplanID, personaltrainerID, clientID)

我试图表明,当私人教练创建营养/训练计划并将其分配给客户时,结果只会显示他们的特定客户,但他们不是客户表中用于识别教练的外键(由于项目的标准)

我想知道培训/营养计划的必要加入的 SQL 是什么。我已经尝试了很长时间,这是我的示例代码。

只有在特定培训师为其分配培训或营养计划时,所需的输出是所有客户数据

在声明中,我遇到了 Bind 参数的问题,因此只有拥有客户端的用户才能看到他们的客户端。如果我使用指定的 ID,我可以获得退货!

    <?php 
            //code to search for a item from the database
            // user can enter any character to search for a value from the db
           if (isset($_POST['search']))
           {
               $valueToSearch = $_POST['ValueToSearch'];
               $query = "select * from client WHERE concat(`clientID`, `name`, `age`, `sex`, `weight`, `height`, `yearsExperience`, `goal`, `injuries`, 'email')like'%".$valueToSearch."%'";
               $search_result = filterTable($query);

           }
           else {
           $query = "select *
            from client
            where clientID in (select clientID from nutrition_plan where personaltrainerID=?)
            or clientID in (select clientID from training_plan where personalTrainerID=?)";
           $query->bind_param("i", $_POST[""]);
               $search_result = filterTable($query);
           }
           //code to filter the db
           function filterTable($query)
           {
               $connect = mysqli_connect("localhost:3308","root","","fypdatabase");
               $filter_Result = mysqli_query($connect, $query);
               return $filter_Result;
           }
           ?>

           <?php
           while($row = mysqli_fetch_array($search_result))
          { //display the details from the db in the table with option to delete or update entry 
            ?>
                    <tr>
                    <td><?php echo $row["clientID"]; ?></td>
                    <td><?php echo $row["name"]; ?></td>
                    <td><?php echo $row["age"]; ?></td>
                    <td><?php echo $row["sex"]; ?></td>
                    <td><?php echo $row["weight"]; ?></td>
                    <td><?php echo $row["height"]; ?></td>
                    <td><?php echo $row["yearsExperience"]; ?></td>
                    <td><?php echo $row["goal"]; ?></td>
                    <td><?php echo $row["injuries"]; ?></td>
                    <td><?php echo $row["email"]; ?></td>
                    <td> 
                        <a href="?Delete=<?php echo $row["clientID"]; ?>" onclick="return confirm('Are you sure?');">Delete</a>
                    </td>
                    <td>
                        <a href="updateClient.php?Edit=<?php echo $row["clientID"]; ?>" onclick="return confirm('Are you sure?');">Update</a>
                    </td>
                  </tr>
                  <?php

【问题讨论】:

  • “如果他们被分配了培训/营养计划” AND 或 OR?
  • 您可能想要一个简单的带有USING(xxxID) 子句的INNER JOIN 链。 dev.mysql.com/doc/refman/8.0/en/join.html
  • 或者!对不起,我做出了改变!
  • 您的查询中有错误SELECT * FROM 然后LEFT JOIN 有完整的条件,并在使用WHERE 进行过滤后
  • @Quasimodo'sclone 谢谢!我该怎么写?

标签: php mysql sql join outer-join


【解决方案1】:
SELECT name, age, location FROM Client
INNER JOIN
(
  SELECT personaltrainerID, clientID from Nutrion_Plan 
  UNION DISTINCT 
  SELECT personaltrainerID, clientID from Training_Plan
) u
USING(clientID)
WHERE u.personaltrainerID = ?;

【讨论】:

  • 谢谢你,太好了!!你会用什么代替“1”而不是这样当不同的教练登录时可以使用不同的personaltrainerID?
  • 当然是像?这样的参数用于准备好的语句。
  • 当我包含一个 ?自己标记不返回结果,是否应该有另一行用于绑定参数?请参阅我上面编辑的示例!
  • 既然您已将您的问题标记为属于 PHP,我希望您想使用 mysqli 或 DBO 的 prepare 方法。 php.net/manual/en/mysqli.quickstart.prepared-statements.php / php.net/manual/en/pdo.prepared-statements.php 强烈建议这样做,因为将客户端数据直接插入 SQL 会使您的应用容易受到 SQL 注入攻击。
  • 我正在使用绑定参数,但是在整数的“i”之后我不知道要传递什么值? $query->bind_param("i", $_POST[""]); ----> 不确定帖子在哪里
【解决方案2】:

让我们看看我是否正确理解您的要求......

仅显示有培训师 123 制定的营养或培训计划的客户:

select *
from client
where clientid in (select clientid from nutrition_plan where personaltrainerid = 123)
   or clientid in (select clientid from training_plan where personaltrainerid = 123);

向这些客户展示他们的所有计划(无论计划的培训师如何):

select *
from client
join
(
  select 'nutrition' as kind, nutritionplanid as id, personaltrainerid, clientid
  from nutrition_plan
  union all
  select 'training' as kind, trainingplanid as id, personaltrainerid, clientid
  from training_plan
) plan using (clientid)
where clientid in (select clientid from nutrition_plan where personaltrainerid = 123)
   or clientid in (select clientid from training_plan where personaltrainerid = 123);

【讨论】:

  • 看起来不错,谢谢!当 pesonaltrainerID 来自数据库并且可以是任何数字时,它会是什么而不是“123”?会是“?”
  • 来自数据库?这是什么意思?从另一个表,例如select personaltrainerid from personal_trainer where name = 'John Smith'?然后你可以简单地用括号中的这个子查询替换 123:... where personaltrainerid = (select personaltrainerid from personal_trainer where name = 'John Smith'));
  • 非常感谢!所以我应该举你的第二个例子,应该有效吗?
  • 如果这是你想要的。尝试并检查结果。该查询会为您提供所有客户及其所有计划,前提是客户的计划中至少有一个是由所需的培训师制定的。
  • 谢谢,我尝试了第一个查询,没有出现错误,但客户端的输出没有显示在表格中!
【解决方案3】:

这应该可以工作

SELECT * from client JOIN nutrition_plan ON client.clientid=nutritionplan.clientid JOIN Personaltrainer ON Personaltrainer.personaltrainerID=nutritionplan.personaltrainerID Where Personaltrainer.personaltrainerID="id"

【讨论】:

  • 感谢卡尚,快到了!然而,最后的“id”又是什么?这就是我的错误所在,personaltrainerID?
  • 这实际上应该通过他的个人 ID 或姓名显示出来
  • 我明白了,它不会抛出任何错误并运行,但是表格中没有显示任何数据!
  • @Darán:此查询为您提供一位私人教练、他们的营养计划和相关客户。如果您按原样进行查询,即直接使用"id",那么您将查找培训师ID 0,因为"id" 表示名为id 的列,并且由于它不存在,MySQL 默认为字符串@987654325 @ 相反,因为这不是一个数字,它被转换为0
猜你喜欢
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 2012-04-24
  • 2018-12-19
  • 2014-08-09
相关资源
最近更新 更多