2012-05-30 70 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