PHP/SQL 替代嵌套 while 循环中的数据库调用


PHP/SQL Alternative to db calls within nested while loops

我的第一篇文章,尽量彻底,如果我弄错了什么,请提前道歉。 我对PHP/SQL也很陌生,所以请耐心等待我。 我发现了几个关于循环中循环的类似问题,但我不确定这些解决方案是否适用于我的情况。

我有两张桌子,tws_workshopNames和tws_workshops。 tws_workshopNames中的主键用作外键,tws_workshops来关联两个表。 我将其分为两个表格的原因是,在许多情况下,在多个日期/时间提供相同的研讨会名称/价格/描述。

无法提交屏幕截图,但以下是 SQL Server 中表设计的简化大纲:

tws_workshopNames:
workshopNameID (pri)
description
price
etc.
tws_workshops:
workshopID (pri)
workshopNameID (foreign)
date
time
etc.

我想要发生的基本上是这样的:

  1. 查询tws_workshopNames表并显示车间名称/价格/描述/等。
  2. 对于每个车间名称,浏览tws_workshops表并显示具有相同车间名称 ID 的所有记录

换句话说,遍历tws_workshopNames并显示第一个车间名称,然后浏览tws_workshops并显示与该车间名称相关的所有记录,然后转到tws_workshopNames中的下一个车间名称,显示与该车间名称相关的所有记录等。

我能够通过在 while 循环

中使用 while 循环来实现所需的结果,其中外部循环调用tws_workshopNames,嵌套循环调用tws_workshops表。 但是,我一直在阅读很多关于此的内容,很明显这不是一个好方法,因为它会导致对数据库的大量调用,但我很难理解任何替代方案。

期望输出:

Workshop 1
price
description
 date (of workshop 1)
 time (of workshop 1)
 ...
Workshop 2
price
description
 first date (of workshop 2)
 first time (of workshop 2)
 second date (of workshop 2)
 second time (of workshop 2)
 third date (of workshop 2)
 third time (of workshop 2)
 ...
Workshop 3
price
description
 date (of workshop 3)
 time (of workshop 3)
 ...
etc.

以下是使用嵌套 while 循环的当前代码:

<?php
// query workshopNames table, what types of workshops are available?
$query = mssql_init("tws_sp_workshopNames", $g_dbc);
// pull up result
$result = mssql_execute($query);
$numRows = mssql_num_rows($result);
while($row = mssql_fetch_array($result)) {
echo "<div style='"...'">
<span class='"sectionHeader'">" . $row['workshopName'] . "</span><br />
<span class='"bodyText'"><strong>" . $row['price'] . "</strong></span><br />
<span class='"bodyText'">" . $row['description'] . "</span>";
$workshopNameID = $row['workshopNameID'];
// query workshops table, what are the dates/times for each individual workshop?
$query2 = mssql_init("tws_sp_workshops", $g_dbc);
mssql_bind($query2, "@workshopNameID", $workshopNameID, SQLVARCHAR);
//pull up result
$result2 = mssql_execute($query2);
$numRows2 = mssql_num_rows($result2);
while($row2 = mssql_fetch_array($result2)) {
echo $row2[date] . "&nbsp;";
echo $row2[time] . "<br />";
};
echo "</div><br />";
};
?>

存储过程非常简单:

tws_sp_workshopNames = "SELECT workshopNameID, workshopName, description, location, price FROM tws_workshopNames"
tws_sp_workshops = "SELECT date, time, maxTeachers, maxStudents, teachersEnrolled, studentsEnrolled FROM tws_workshops WHERE workshopNameID=@workshopNameID"

希望这一切都相对清楚,我真正正在寻找的是获得相同结果的更好方法,即不涉及循环内数据库调用的解决方案。

提前感谢您的任何帮助,几天来一直把我的头撞到这个......

在这种情况下避免使用循环查询是正确的(因为只需在一个查询中使用一个简单的 JOIN 即可获得所需的结果)。

我也会避免使用 GROUP_CONCAT(),因为有字符限制(默认情况下,您可以更改它),而且您必须解析它输出的数据,这有点痛苦。我只会通过加入并获取每一行来获取您需要的所有数据。然后使用车间 ID 作为键将数据加载到数组中,但保持数组打开状态以将每个时间数据追加为新数组:

$workshops[$workshop_name][] = $timesArray;

然后在输出上,您可以循环,但不必在每次调用时都命中数据库:

foreach ($workshops as $workshop_name => $times)
{
  echo $workshop_name;
  foreach ($times as $time)
  {
    echo $time;
  }
  echo "<br>";
}

这不是确切的代码,正如您在问题中指出的那样,您希望保留/显示有关研讨会的其他一些信息 - 只需使用数组结构,直到您在层次结构中获得所需的所有数据。如果你试图建立一个深树结构,你可以使用类似 http://kevin.vanzonneveld.net/techblog/article/convert_anything_to_tree_structures_in_php/的东西,但我认为这对这个例子来说是矫枉过正的。

由于这是我所说的"中级"问题,我认为您应该尝试使用我的建议来解决它(这就是使您成为一名优秀程序员的原因,而不是复制/粘贴)。如果您遇到困难,请发表评论,我会进一步帮助您。

我认为你做事的方式没有任何问题。 我想您可以连接结果,然后使用一个查询在应用程序中操作输出。 您的查询可能如下所示

SELECT
    n.workshopNameId,
    n.price,
    n.description,
    GROUP_CONCAT(w.date) as dates,
    GROUP_CONCAT(w.time) as times
FROM tws_workshopNames n
INNER JOIN tws_workshops w USING(workshopNameID)
GROUP BY n.workshopNameID