我有两个MySQLi查询,我正试图将它们转换为一个联接查询。它在某种程度上起作用,但它并没有按照我希望的方式起作用。
我有两张桌子、票和回复。我从票证查询中选择信息,从存储了票证id的回复表中选择信息。到目前为止,我正在输出初始ticket消息和第一个回复,但它会对该ticket的每个回复重复此操作。所以我目前的输出是:
Initial message
First reply
Initial message
Second reply
Initial message
Third reply
它为该票证的每个回复输出初始消息。我只希望它输出一次初始消息,然后输出此票证的回复。到目前为止,我已经尝试了几种不同的方法来执行这个联接查询,但这就是我现在所拥有的:
$ticket = $db->conn->query("SELECT tickets.client, tickets.subject, tickets.message, tickets.created_at, tickets.status,
replies.reply_username, replies.reply_message, replies.reply_time
FROM tickets, replies
WHERE tickets.id = replies.ticket_id") or die(mysqli_error($db->conn));
我做错什么了吗?我的逻辑有错吗?
我还想补充一下,我以前的查询有"INNER join"answers"left join",但INNER给我的输出与我目前的相同。
有点混乱,但这是在查询之后运行的代码。
while($rows = $ticket->fetch_object()) {
if($_SESSION['ticket_username'] == $rows->client) {
$status = $rows->status;
echo '
<h3>'.$rows->subject.'</h3>
<small>Created by '.$rows->client.', '.$timeAgo->inWords($rows->created_at).'</small>
<hr>
<p>'.nl2br($rows->message).'</p>
<hr>
<small>Reply from '.$rows->reply_username.', '.$timeAgo->inWords($rows->reply_time).'</small>
<p>'.nl2br($rows->reply_message).'</p>
<hr>
';
} else {
header("Location: index");
}
if(!empty($errors) && is_array($errors)) {
foreach($errors as $error) {
echo $error;
}
}
}
您没有给出太多内容,但您的查询似乎可以(基于逻辑),只留下一个可能的罪魁祸首。
默认情况下,PDO使用PDO::FETCH_BOTH
作为其获取结果。这意味着它将每一列映射到其名称和"integer"列名。
您可能需要在查询中使用$statement->fetchAll(PDO::FETCH_ASSOC);
来获得期望的输出。
点击此处阅读更多关于PDOStatement::fetchAll的信息。
这可能需要一些调整,但我的方法是:
while($rows = $ticket->fetch_object()) {
if($_SESSION['ticket_username'] == $rows->client) {
$status = $rows->status;
if($lastID != $rows->id){
echo '
<h3>'.$rows->subject.'</h3>
<small>Created by '.$rows->client.', '.$timeAgo->inWords($rows->created_at).'</small>
<hr>
<p>'.nl2br($rows->message).'</p>
<hr>';
}
$lastID = $rows->id;
echo '
<small>Reply from '.$rows->reply_username.', '.$timeAgo->inWords($rows->reply_time).'</small>
<p>'.nl2br($rows->reply_message).'</p>
<hr>';
} else {
header("Location: index");
}
if(!empty($errors) && is_array($errors)) {
foreach($errors as $error) {
echo $error;
}
}
}
这样做的目的是检查当前打印的机票ID是否与上次打印的相同;如果是,请不要再打印初始消息。我不确定您的查询是如何对结果进行排序的,所以您可能需要一个ORDER BY ticket.id, replies.ticket_id
来确保它们都分组在一起。