2012-05-30 41 views
0

我的第一篇文章,尽可能地做到尽可能详尽,如果我弄错了某些东西,请提前道歉。我是PHP/SQL的新手,请耐心等待。我发现了几个有关循环内循环的类似问题,但我不确定这些解决方案适用于我的情况。PHP/SQL在嵌套while循环中替代db调用

我有两个表,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表显示workshopName /价格/说明/等。
  2. 每个workshopName经过tws_workshops表,并显示具有相同workshopNameID

换句话说所有记录,经过tws_workshopNames并显示第一workshopName,然后通过tws_workshops并显示相关的所有记录然后转到tws_workshopNames中的下一个workshopName,显示与该workshopName相关的所有记录。

我能够通过在while循环中使用while循环来实现期望的结果,其中外循环执行呼叫tws_workshopNames和嵌套循环调用tws_workshops表。不过,我一直在阅读很多关于这方面的内容,很明显这不是一个好方法,因为它会导致对db的很多调用,但我很难理解任何替代方法。

所需的输出:

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 [email protected]" 

希望这一切相对清晰,我真正想要的是获得相同结果的更好方法,即一个解决方案s不涉及循环内的数据库调用。

在此先感谢您的帮助,已经连续几天敲我的头这一个...

回答

0

你是正确的,以避免在这种情况下,循环查询(因为期望的结果可以实现只是一个简单的在一个查询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/,如果你正在试图建立一个深树结构,但我认为这是矫枉过正的这个例子。

由于这是我所谓的“中间层”的问题,我想你应该尝试通过它的工作(这是什么使你成为一个优秀的程序员,而不是复制/粘贴),使用我的建议。如果你遇到困难,评论和我会进一步帮助你。

+0

非常感谢这些信息。我曾经见过一些关于使用JOIN用于类似目的的提及,但很难理解它如何让我在需要的地方。绝对感谢你对自己的工作做出的评论,并且会这样做。显然我需要花一些时间来玩一般的数组。如果我遇到障碍,我会再次检查。干杯。 – washe

+0

只是想想你真正想要的数据。你真的希望所有的时间都与车间名称和价格挂钩。标题只是一个显示问题。所以你希望你的结果查询包括所有时间(select * from times和LEFT JOIN the workshop table for names and prices)。当编写SQL查询,我往往决定哪个单个表将返回人数最多的记录,那么就LEFT JOIN需要匹配剩余的数据。根据我的经验,这种方法适用于大约80%的需要编写的SQL查询。再次 – solidau

+0

感谢您的信息,试图通过工作的另一桩去希望回到这个很快。希望我可以放开这件事,直到我能回到它为止。 – washe

0

我看不出什么毛病,你正在做的事情的方式。我想你可以连接结果,然后使用一个查询来处理应用程序中的输出。您的查询可能看起来像

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 
+0

感谢您的快速反应。上面的工作,但经过大量的阅读我的理解是,在一个循环内有一个数据库调用是不好的做法。我相信这个想法是,它使得更多的数据库调用比必要的,并会放慢服务器。我会看看我能用你的连接建议做些什么。再次感谢。 – washe

+0

更多的调用并不一定意味着更多的执行时间。来自* SQL Antipatterns *:'程序员有一种本能,SQL查询越少,性能就越好。假设有问题的SQL查询具有相同的复杂性,这是真实的。在另一方面,单个怪物查询的成本成倍增加,直到它的更经济的使用几个简单的queries.'取决于你的情况,你要完成什么。直到你注意到它成为一个问题,我才会担心。您可以缓存查询以提高性能。 –

+0

这确实有道理,我会牢记这一点。再次感谢您的输入! – washe