【问题标题】:mysql query return first match of each resultmysql查询返回每个结果的第一个匹配
【发布时间】:2013-10-22 01:36:56
【问题描述】:

我有一个可以正常工作的聊天系统,但是我刚刚实现的消息列表会拉取每个人的每条消息然后显示最后一个结果,这显然是对资源的巨大浪费和服务器的压力,只返回一个结果每个用户。

这是检索消息列表的查询,然后有一个 while 循环清理数组以仅显示每个用户的最新消息,我知道使用 JOIN 有更好的方法来做到这一点,但我可以'别想了。

$result = dbconstruct("SELECT messages.id, messages.msgfrom, messages.msg, 
messages.active, messages.replied, users.username, users.online, users.admin, 
users.imagename FROM messages, users WHERE msgto='$_SESSION[id]' 
AND users.id=msgfrom ORDER by messages.id DESC");

我查看了其他答案,但如前所述,发现很难掌握连接技术。

更新

我认为我没有很好地解释我需要什么。目前我运行上述查询,返回大约 2000 个结果,然后使用它来将每个用户的消息过滤为一条消息。

$clean = array(); while($result->fetch_assoc()) { if(in_array($result[msgfrom],     
$clean)) { }
else { //print message }

$usercheck = array_push($clean, $result[msgfrom]); }

这可以很好地显示消息列表,并且只显示来自每个用户的最后一条消息,但这样做是一种非常糟糕的方式。在 SQL 查询中必须有一种方法可以做到这一点。

【问题讨论】:

  • php 代码如何清理这个结果?
  • 你不需要加入,只需要 LIMITORDER 子句或两者都需要

标签: php mysql


【解决方案1】:

假设 message.id 是 auto_incremented,MAX 是最新的。否则,如果您有一个列作为时间戳,您可以使用它并应用相同的原则。

我认为复制您在 php 中尝试的最准确的形式是仅选择来自某人的最新消息(子查询)并将其与您想要的输出查询连接。我认为它会返回您所期望的:

SELECT m.id,
  m.msgfrom,
  m.msg,
  m.active,
  m.replied,
  u.username,
  u.online,
  u.admin,
  u.imagename
FROM messages m 
INNER JOIN users u ON u.users.id = m.msgfrom
INNER JOIN (SELECT MAX(id) as id, msgfrom
            FROM messages
            GROUP BY msgfrom
           ) m2
    ON m2.id = m.id AND m2.msgfrom = m.msgfrom
WHERE messages.msgto = '$_SESSION[id]'

【讨论】:

  • 据我了解,使用 MAX 函数,它只会返回一个值,我需要它为每个 messages.msgto 返回 MAX messages.id 结果,这有意义吗?
  • @AndrewWard。我添加了一种不同的方法,我认为它可能更接近你想要的。
  • @AndrewWard。你成功了吗?如果没有,您可能需要显示一些示例数据,以便更轻松地提供帮助。
  • 我最终使用了一个 while 循环来仅检索每条用户消息的最后一条消息。但是您的解决方案也可以工作,并且从技术上讲会比使用多个数据库查询更有效,因此我将标记为已接受的解决方案。
【解决方案2】:

在使用连接的情况下,您的查询应该如下所示:

SELECT 
    messages.id, 
    messages.msgfrom, 
    messages.msg,
    messages.active, 
    messages.replied, 
    users.username, 
    users.online, 
    users.admin, 
    users.imagename 
FROM 
    messages
INNER JOIN 
    users 
ON 
    users.id = messages.msgfrom
WHERE 
    msgto='$_SESSION[id]' 
ORDER by 
    messages.id 
DESC

显然它还没有经过测试,你绝对应该阅读一下figure out which join to use.

【讨论】:

  • 假设 user.a 中有 1000 行具有 msg.to = '$_SESSION[id] 然后对于 user.b 也是如此。我想显示来自 user.a 和 user.b 的最后一条消息等等.. 不必检索所有 1000 条消息来显示来自每个用户的最后一条消息...如何将每个结果限制为一行。
  • @AndrewWard 你应该可以输入LIMIT 1 来只检索最新的吗?
  • 对不起,我不能说得不够清楚,有来自不同用户的多条消息将具有 msg.to = $_SESSION[id] 我需要返回每个用户的最后一条消息,而不仅仅是限制一个结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-17
相关资源
最近更新 更多