1

我有一个通知系统(基于 PHP、MySQL),我正在尝试执行以下操作:查询按帖子分组的通知结果,没有任何限制,但按 time_sent 排序,限制为 5(每次迭代)。然后我使用 ajax 来显示下一个迭代集 5 个通知。

基本上我一次需要 5 个通知(每组),但是对于每个通知,如果一个组涉及一个帖子:可以有尽可能多的通知:

这将是如何显示的:

  1. 关于帖子 F 的通知 – 1 天前发送
  2. 关于帖子 C 的第一次通知 – 2 天前发送
    • 关于帖子 C 的第二次通知 – 3 天前发送
    • 关于 C 帖子的第三次通知 – 4 天前发送
    • 关于 C 帖子的第四次通知 – 5 天前发送
  3. 关于帖子 Y 的通知 – 3 天前发送
  4. 关于 D 后的第一次通知 – 4 天前发送
    • 关于 D 后的第二次通知 – 5 天前发送
    • 关于 D 后的第三次通知 – 6 天前发送
  5. 关于帖子 Y 的通知 – 5 天前发送

如果发送了关于帖子 Y 的新通知,这将自然地上升到列表的顶部。

在我决定实施这个小组系统之前,我就是这样开始的:

$notifications_req = mysql_query('SELECT * FROM notifications WHERE user_id = "'.$user_id.'" ORDER BY time_sent DESC LIMIT 5');

现在我迷路了,按照逻辑顺序与这个群体斗争。

数据库当然包含一post_id列。

编辑:

我最终彻底改变了我想要排序通知的方式。这就是我最终做到的方式。它可能不是最有效的,但它按我想要的方式工作:

<?php  $notifications_all_req = mysql_query('SELECT * FROM notifications WHERE user_id = "'.$user_id.'" ORDER BY time_sent DESC');  if(mysql_num_rows($notifications_all_req) > 0){
while($row =  mysql_fetch_assoc($notifications_all_req))
{
    $post_req_ids[] = $row['post_id'];
}
$unique_post_ids = array_unique($post_req_ids);
foreach ($unique_post_ids as $i => $unique_post_id)
{
    ?>      
    <ul id="notifications_ul_<?php echo $i; ?>">
    <?php
    $notifications_req = mysql_query('SELECT * FROM notifications WHERE (user_id = "'.$user_id.'" AND post_id = "'.$unique_post_id.'") ORDER BY time_sent DESC ');
        while($notification =  mysql_fetch_assoc($notifications_req))
        {

        }
        ?>
    </ul>
    <?php
}  }  ?>

这样,我可以控制通知组(使用$i)和每个组中的通知组的限制,也可以使用 Ajax 为后者加载更多代码。

4

1 回答 1

1

您不想在GROUP BY此处使用,因为那是用于摘要查询。

专业提示:不要使用SELECT *. 相反,请按名称选择所需的列。

专业提示:人们建议您使用 PDO 或 mysqli_ 是有充分理由的。mysql_ 接口是出了名的不安全。如果你把一个基于 mysql_ 的 web 应用程序放在公共网络上,一些坏人pwn 你。如果您不介意被控制,例如,如果您正在构建原型或概念验证网站,请不要担心。

让我们在开始将其分割成五个后的块之前获得结果集的排序。您的ORDER BY条款中需要两个项目。看来您希望您的结果集像这样排序。

SELECT * 
  FROM notifications 
 WHERE user_id = ? 
 ORDER BY post_id, time_sent DESC

试一试,不带LIMIT 5, 并调试您的 php 代码,以便获得良好的显示效果,即使它对于您的目的来说太长了。

接下来,如果我对您的理解正确,您将尝试一次显示五个帖子。这变得更加棘手,因为您需要五个帖子,并且每个帖子都可以有可变数量的通知。

所以我们必须想出一种方法来一次获得五个帖子。这个子查询会这样做,给出一个包含五个 post_id 值的列表。

 SELECT DISTINCT post_id
   FROM notifications
  WHERE user_id = ?
  ORDER BY post_id
  LIMIT 5 OFFSET ?   

参数 toOFFSET ?应该是 0、5、10 等等,以获取第一个、第二个、第三个等,五个帖子。如果您只想要前五个帖子,请忽略该OFFSET子句。

现在我们必须在另一个查询中嵌入仅获取五个帖子的子查询以获取所有数据。像这样工作。

SELECT * 
  FROM notifications 
 WHERE post_id IN (
                      SELECT DISTINCT post_id
                        FROM notifications
                       WHERE user_id = ?
                       ORDER BY post_id
                       LIMIT 5 OFFSET ?   
                  ) 
 ORDER BY post_id, time_sent DESC

最后一个更复杂的 SQL 查询将给出一个与第一个语句相似的结果集。您应该能够将它插入到您调试的 php 代码中并获得您正在寻找的显示。

于 2013-10-28T13:14:22.380 回答