[英]Looping through MySQL left join in php vs. 2 separate queries
我的網站上有一個簡單的問答部分,允許評論。 我目前使用循環和$ _GET ['id']值填充答案。 這是我的查詢
<?php
try{
$parent=$_GET['id'];
$post_type = "2";
$stmt = $dbh->prepare(
"SELECT p.post_id, p.content, p.author, p.created, pc.comment_id AS comment_id, pc.content AS comment_content
FROM posts AS p
LEFT JOIN posts_comments AS pc
ON p.post_id = pc.parent_id
WHERE p.post_type = :post_type AND p.parent = :parent ");
$stmt->bindParam(':parent', $parent, PDO::PARAM_INT);
$stmt->bindParam(':post_type', $post_type, PDO::PARAM_INT);
$stmt->execute();
$answers_array = array();
while ($answers = $stmt->fetch(PDO::FETCH_ASSOC)) {
$answers_array[]= $answers;
}
}
?>
這將在數組中返回以下結果
Array (
[0] => Array (
[post_id] => 12
[content] => I have an answer
[author] => Author1
[created] => 2012-06-09 21:43:56
[comment_id] =>
[comment_content] => )
[1] => Array (
[post_id] => 13
[content] => My second answer
[author] => Author1
[created] => 2012-06-10 06:30:58
[comment_id] => 35
[comment_content] => 1st comment )
[2] => Array (
[post_id] => 13
[content] => My second answer
[author] => Author2
[created] => 2012-06-10 06:30:58
[comment_id] => 36
[comment_content] => 2nd comment )
[3] => Array (
[post_id] => 13
[content] => My second answer
[author] => Author2
[created] => 2012-06-10 06:30:58
[comment_id] => 37
[comment_content] => 3rd comment )
)
在我的question.php頁面上,我知道我需要用類似的東西來循環這些結果
<?php $answer_count = count($answers_array);
for($x = 0; $x < $answer_count; $x++) {
$answers = $answers_array[$x];
}
?>
我的問題 -
我不知道是否使用兩個單獨的查詢來提取與每個答案相關的注釋或使用我上面的連接並使用php構建另一個數組。 老實說,我不知道怎么做。 如果我使用連接,我想要一個看起來像這樣的數組,但我不知道如何使用php中的循環來構建它。
Array (
[0] => Array (
[post_id] => 12
[content] => I have an answer
[author] => Author1
[created] => 2012-06-09 21:43:56
[comment_id] =>
[comment_content] => )
[1] => Array (
[post_id] => 13
[content] => My second answer
[author] => Author1
[created] => 2012-06-10 06:30:58
Array(
[1] => Array (
[comment_id] => 35
[comment_content] => 1st comment)
[2] => Array (
[comment_id] => 36
[comment_content] => 2nd comment)
[3] => Array (
[comment_id] => 37
[comment_content] => 3rd comment))
一旦我有了這樣的數組,我想我可以在question.php頁面上的原始php循環中為每個進行一次。
一個查詢很好。 就像你擁有它,也許是更好的opton。 你必須找出哪個更有效率,讓MySQL承受壓力,或者網絡和PHP承受壓力。 讓PHP承受壓力要比MySQL好多了,但是MySQL具有“內置”功能,例如你想要的分組,然后離開MySQL並節省網絡流量。
要使其工作:在查詢中添加“ORDER BY p.post_id,pc.comment_id” - 這將按順序獲取結果。
然后,如果你必須構建一個數組(雖然你可以直接處理而不使用數組,方法將類似):
$lastPostID = 0;
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($lastPostID <> $row['post_id']) {
$lastPostID = $row['post_id'];
$answers[$lastPostID] = array('post_id' => $row['post_id'],
'author_id' => $row['author_id'],
etc
'comments' => array() );
}
$answers[$lastPostID]['comments'][] = array('comment_id' => $row['comment_id'], 'coment' => $row['comment'] etc);
}
這是你的選擇。 每個都有它們的優點和缺點。 使用單個查詢(顯然,單個數據庫調用),您只需要遍歷數據集一次,但您有可能返回重復數據。 使用多個查詢,您只需提取所需的數據,但(顯然,多個數據庫調用和)您必須迭代多組數據。
下面是單個查詢方法的臟實現(相同的基本流程適用於多查詢方法,除了注釋構建是它自己的循環)。 但基本的想法是存在的。 您有一個答案地圖,在迭代記錄時添加/檢索它們,並附加注釋。
while ($answers = $stmt->fetch(PDO::FETCH_ASSOC))
{
$post_id = strval($answers['post_id']);
if(!array_key_exists($post_id, $answers_array)) {
$answers_array[$post_id] = array(
'post_id' => $answers['post_id'],
// ... assign other stuff ...
'comments' => array()); //initialize the comments array
}
if(!empty($answers_array['comment_id'])) {
$obj = $answers_array[$post_id];
$obj['comments'][] = array(
'comment_id' => $answers['comment_id'],
'comment_content' => $answers['comment_content']);
}
}
您將希望使用JOIN通過單個查詢返回所有結果,否則,您將進行多個查詢,每個帖子一個。 通過發出許多單獨的查詢,您將獲得大量開銷。
如果您想返回非常少量的帖子結果,則會有例外。
請務必通過post_id,comment_id對查詢進行ORDER。
要迭代組合結果,它看起來像這樣:
$post_id = 0;
foreach($rows as $row) {
// See if our post changed
if ($post_id != $row['post_id']) {
// Display the post and post header
..
// Update the current post_id variable
$post_id = $row['post_id'];
}
// Display the comment
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.