SQL MAX()在多个查询字符串中

时间:2010-09-22 23:00:25

标签: php sql mysql

我有一串3个查询,旨在

  1. 查找哪些消息包含具有相同ID的其他消息,表示回复
  2. 查找第一个查询的结果中哪些消息具有指定用户作为输入该消息字符串的第一条消息(最小时间戳)
  3. 查找该字符串消息的最新消息(最大时间戳)
  4. 问题来自第三个查询。我得到了第二个查询的预期结果,然后当执行第三个查询时,没有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 ;
    

1 个答案:

答案 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}}

这将选择由具有响应的指定用户启动的所有线程以及最近的响应。