我有一串3个查询,旨在
问题来自第三个查询。我得到了第二个查询的预期结果,然后当执行第三个查询时,没有MAX(时间戳)作为最大值,我得到了预期的结果。当我添加它时,我只获得每个消息字符串的第一条消息,无论我是使用min还是max,行计数表示当显示2行时返回1行。有人对我出错的地方有任何想法吗?
$sql="SELECT reply_chunk_id
FROM messages
GROUP BY reply_chunk_id
HAVING count(reply_chunk_id) > 1 ";
$stmt16 = $conn->prepare($sql);
$result=$stmt16->execute(array('specified_user'));
while($row = $stmt16->fetch(PDO::FETCH_ASSOC)){
$sql="SELECT user,reply_chunk_id, MIN(timestamp) AS grp_timestamp
FROM messages WHERE reply_chunk_id=?
GROUP BY reply_chunk_id HAVING user=?";
$stmt17 = $conn->prepare($sql);
$result=$stmt17->execute(array($row['reply_chunk_id'],'specified_user'));
while($row2 = $stmt17->fetch(PDO::FETCH_ASSOC)){
$sql="SELECT message, MAX(timestamp) as max FROM messages WHERE reply_chunk_id=?";
$stmt18 = $conn->prepare($sql);
$result=$stmt18->execute(array($row2['reply_chunk_id']));
while($row3 = $stmt18->fetch(PDO::FETCH_ASSOC)){
echo '<p>'.$row3['message'];
}
}
}
echo ' '.$stmt18->rowCount();
根据要求创建消息的表视图:
CREATE TABLE IF NOT EXISTS `messages` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`timestamp` int(11) NOT NULL,
`user` varchar(25) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT 'anonimous',
`message` varchar(2000) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`topic_id` varchar(35) NOT NULL,
`reply_chunk_id` varchar(35) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
答案 0 :(得分:1)
由于message
未分组,因此您将获得message
组中message
的确切内容SELECT message, timestamp AS max
FROM messages
WHERE reply_chunk_id=:rcid
AND timestamp=(SELECT MAX(timestamp)
FROM messages
WHERE reply_chunk_id=:rcid)
。如果您希望SELECT message, timestamp AS max
FROM messages
WHERE reply_chunk_id=?
ORDER BY timestamp DESC, id
LIMIT 1
具有isn't defined时间戳,则需要明确选择它:
id
或:
while
第二个查询通过选择具有最高if
的消息来打破关系(在非常不可能但可能的情况下,多个人同时发布)。
您在循环中设置的许多变量都是不变的,因此应该移到循环之外。
$ stmt17将返回最多1个结果。而且,$ stmt18将返回总是返回一个结果。将第二个内部$stmt18
循环(对于$ stmt17)重写为try {
$threadSql="SELECT reply_chunk_id
FROM messages
GROUP BY reply_chunk_id
HAVING count(reply_chunk_id) > 1 ";
$firstUserSql="SELECT user, MIN(timestamp) AS grp_timestamp
FROM messages WHERE reply_chunk_id=?
GROUP BY reply_chunk_id HAVING user=?";
$lastMsgSql="SELECT message, MAX(timestamp) as max FROM messages WHERE reply_chunk_id=?";
$threadQuery = $conn->prepare($threadSql);
$threadQuery->setFetchMode(PDO::FETCH_ASSOC);
$firstUserQuery = $conn->prepare($firstUserSql);
$lastMsgQuery = $conn->prepare($lastMsgSql);
$result=$threadQuery->execute(array('specified_user'));
foreach ($threadQuery AS $thread){
$result=$firstUserQuery->execute(array($thread['reply_chunk_id'],'specified_user'));
if (FALSE !== ($firstUser = $firstUserQuery->fetch(PDO::FETCH_ASSOC))) {
$result=$lastMsgQuery->execute(array($thread['reply_chunk_id']));
$lastMsg = $lastMsgQuery->fetch(PDO::FETCH_ASSOC);
echo '<p>'.$lastMsg['message'].'</p>';
}
}
echo ' ' . $lastMsgQuery->rowCount();
} catch (PDOException $exc) {
...
}
语句,并简单地从SELECT mchunk.reply_chunk_id,
muser.user, MIN(muser.`timestamp`) AS grp_timestamp,
mmax.message, mmax.`timestamp` AS max
FROM messages AS mchunk
JOIN messages AS muser
ON mchunk.reply_chunk_id = muser.reply_chunk_id
JOIN messages AS mmax
ON mchunk.reply_chunk_id = mmax.reply_chunk_id
WHERE mmax.timestamp=(SELECT MAX(timestamp) FROM messages AS m WHERE m.reply_chunk_id=mchunk.reply_chunk_id)
GROUP BY mchunk.reply_chunk_id, muser.user
HAVING count(mchunk.reply_chunk_id) > 1
AND muser.user IN ('steve', '0010')
;
获取结果将与目的相同且更清晰。
{{1}}
最后,单个SQL语句可以替换大部分PHP代码:
{{1}}
这将选择由具有响应的指定用户启动的所有线程以及最近的响应。