Php 多查询字符串中的SQL MAX()
我有一个由3个查询组成的字符串,用于Php 多查询字符串中的SQL MAX(),php,sql,mysql,Php,Sql,Mysql,我有一个由3个查询组成的字符串,用于 查找哪些邮件具有表示答复的相同id的其他邮件 查找来自第一个查询的结果的哪些消息具有指定的用户,以输入该消息字符串的第一条消息(最小时间戳) 查找该消息字符串的最新消息(最大时间戳) 问题来自第三个查询。在第二个查询之前,我得到了预期的结果,然后在执行第三个查询时,没有MAX(timestamp)作为MAX,我得到了预期的结果。当我添加它时,我只会在每个消息字符串应该是最后一个消息时获得第一个消息,而不管我使用的是最小还是最大,并且当显示2行时,行计数表示返
$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();
由于
消息
未分组,因此您将从组中获得确切的消息
。如果您想要带有时间戳的消息
,则需要显式选择它:
SELECT message, timestamp AS max
FROM messages
WHERE reply_chunk_id=:rcid
AND timestamp=(SELECT MAX(timestamp)
FROM messages
WHERE reply_chunk_id=:rcid)
或:
第二个查询通过选择具有最高id
的消息来打破联系(在不太可能但可能有多人同时发布的情况下)
一般反馈
在循环中设置的许多变量是不变的,因此应该移到循环之外
$stmt17将最多返回一个结果。此外,$stmt18将始终只返回一个结果。将第二个内部while
循环(对于$stmt17)重写为if
语句,并简单地从$stmt18
中获取结果,就目的而言,这是等效的、更清晰的
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) {
...
}
这将选择指定用户启动的所有具有响应的线程,以及最近的响应。您的消息是否具有唯一id?(提示:发布您的
CREATE TABLE
语句)。是的,它们有一个名为id的字段,该字段是自动递增的,reply\u chunk\u id但是可以与其他消息相同,因为相同的回复id表示相关的回复消息,我将发布表创建如果您对中间结果感兴趣,或者“选择”是一个可行的答案吗?我对intermediate不感兴趣,只是用户启动的线程的最大时间戳的结果,这是一个称为“最新回复”的排序视图,其中每个线程的最新回复基本上显示为快照。我非常感谢您的帮助,你在帮助我发展技能和回答我的问题方面做得非常出色。我只是有一些简短的问题。1.像您建议的那样的sql查询不会占用很多资源吗?2.我不完全确定你的第一个建议是怎么回事,因为我对php编程还是有点陌生,而且使用了相当简单的技术。我不理解的部分是if(虚线,我以前从未见过。3.我注意到您使用了try-and-catch。我应该在每个查询中使用它吗?再次感谢您的帮助。1.这取决于有多少个结果。使用多个查询也会对服务器资源产生负面影响,并且可能需要更长的时间。一般来说,最好不要使用数据库处理需要组合与给定属性匹配的数据的任务(将SQL语句视为声明属性;DBMS返回具有这些属性的数据)。这就剩下了更改任务(例如显示数据)对于编程语言。2.这一行可以很容易地分成两行:赋值和与FALSE的比较。当没有更多行时,从DB查询中获取结果通常返回FALSE;mysql、mysqli和PDO驱动程序都会这样做。如果查询将返回0或1行,则If
可以通过检查获取的v值为FALSE。!==
类似于!=
,但不处理类型;FALSE==0
,但FALSE!==0
。3.您应该始终处理错误。try/catch假设您已将错误模式设置为PDO::ERRMODE\u异常
,在这种情况下,try/catch是必需的。有时设置t更合理他将错误模式转换为其他模式,并检查返回成功或失败的方法的返回值(例如PDOStatement::execute),但将一系列PDO方法调用封装在一个try/catch中通常更容易理解,因为调用通常需要按顺序成功完成。更大、更复杂的变化是分离访问数据库的代码(也称为数据访问层)来自表示数据的代码。这些是不同的,分离它们可以让您轻松地更改其中一个而不影响另一个,并提供相同数据的不同表示。应用是实现这种分离的一种方法。
SELECT message, timestamp AS max
FROM messages
WHERE reply_chunk_id=?
ORDER BY timestamp DESC, id
LIMIT 1
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')
;