我有一个查询,获取消息系统的主要页面(包括未读消息计数等)所需的所有信息…但它当前正在检索原始的线程消息.我想增加以下查询,以获取每个线程中最新的消息.

这个查询非常接近,但是我的平庸的sql技能让我无法包装…

$messages = array();
$unread_messages_total = 0;

$messages_query = "
SELECT m.*,COUNT(r.id) AS num_replies,MAX(r.datetime) AS reply_datetime,(m.archived NOT LIKE '%,".$cms_user['id'].",%') AS message_archive,(m.viewed LIKE '%,%') AS message_viewed,SUM(r.viewed NOT LIKE '%,%') AS unread_replies,CASE
        WHEN MAX(r.datetime) >= m.datetime THEN MAX(r.datetime)
        ELSE m.datetime
        END AS last_datetime
FROM directus_messages AS m
LEFT JOIN directus_messages as r ON m.id = r.reply
WHERE m.active = '1'  
AND (m.to LIKE '%,%' OR m.to = 'all' OR m.from = '".$cms_user['id']."') 
GROUP BY m.id
HAVING m.reply = '0' 
ORDER BY last_datetime DESC";

foreach($dbh->query($messages_query) as $row_messages){
    $messages[] = $row_messages;
    $unread_messages_total += (strpos($row_messages['archived'],','.$cms_user['id'].',') === false && ( (strpos($row_messages['viewed'],') === false && $row_messages['unread_replies'] == NULL) || ($row_messages['unread_replies']>0 && $row_messages['unread_replies'] != NULL) ) )? 1 : 0;
}

提前感谢您提供的任何帮助!

编辑:(数据库)

CREATE TABLE `cms_messages` (
  `id` int(10) NOT NULL auto_increment,`active` tinyint(1) NOT NULL default '1',`subject` varchar(255) NOT NULL default '',`message` text NOT NULL,`datetime` datetime NOT NULL default '0000-00-00 00:00:00',`reply` int(10) NOT NULL default '0',`from` int(10) NOT NULL default '0',`to` varchar(255) NOT NULL default '',`viewed` varchar(255) NOT NULL default ',`archived` varchar(255) NOT NULL default ',PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

编辑2:(要求)

>返回特定user_id的所有父消息:$cms_user [‘id’]
>返回该父消息的回复数:num_replies
>返回该父消息的未读回复数:unread_replies
>返回父消息的日期或最近的回复:last_datetime
>返回消息是否在归档文件中:message_archive
>返回消息是否已被查看:message_viewed
>以DESC datetime顺序返回所有消息
>返回最新消息,从父或回复如果有一些(如gmail)

如果您只有两个级别的消息(即只有父消息和直接答复),则可以尝试此查询:
select
    root_message.id,root_message.active,root_message.subject,case
        when max_reply_id.max_id is null then 
            root_message.message
        else
            reply_message.message
    end as message,root_message.datetime,root_message.reply,root_message.from,root_message.to,root_message.viewed,root_message.archived
from
    -- basic data
    cms_messages as root_message
    -- ID of last reply for every root message
    left join (
        select 
            max(id) as max_id,reply as parent_id 
        from 
            cms_messages
        where
            reply <> 0 
        group by 
            reply
    ) as max_reply_id on max_reply_id.parent_id = root_message.id                                              
    left join cms_messages as reply_message on reply_message.id = max_reply_id.max_id
where
    root_message.reply = 0

它使用子查询max_reply_id作为数据源来选择最新答案的ID.如果存在(即,如果有答案),则使用reply_message.message.如果不存在(根消息未找到答案),则使用root_message.message.

你也应该考虑表的结构.例如,如果回应包含NULL(如果是父消息)或现有消息的ID,则会更有意义.目前,您将其设置为0(不存在的消息的ID),这是错误的.查看和归档的类型也很奇怪.

编辑:你也应该避免使用having子句.在可能的地方使用.

这是一个满足您的要求的新查询.如果它有任何问题(即如果它返回错误的数据),让我知道.

像第一个查询一样,它:

>使用子查询reply_summary来累积关于回复的数据(最后回复的ID,回复的数量和未读回复的数量);
>将此子查询加入到基表中;
>根据reply_summary.max_reply_id将cms_messages作为reply_message连接到子查询,以获取有关最后一个回复(消息,datetime)的数据.

我已经简化了你如何确定last_datetime的方式 – 它现在需要上次回复的时间(如果有任何回复)或原始帖子的时间(当没有发现回复时).

我没有过滤回复和来自字段.如果有必要,应该更新reply_summary子查询的where子句.

select
    parent_message.id,parent_message.subject,parent_message.message,parent_message.from,parent_message.to,coalesce(reply_summary.num_replies,0) as num_replies,last_reply_message.datetime as reply_datetime,(parent_message.archived NOT LIKE '%,{$cms_user['id']},(parent_message.viewed   LIKE     '%,reply_summary.unread_replies,coalesce(last_reply_message.message,parent_message.message) as last_message,coalesce(last_reply_message.datetime,parent_message.datetime) as last_datetime
from
    cms_messages as parent_message
    left join (
        select
            reply as parent_id,max(id) as last_reply_id,count(*) as num_replies,sum(viewed not like '%,%') as unread_replies
        from
            cms_messages
        where
            reply <> 0 and
            active = 1
        group by
            reply
    ) as reply_summary on reply_summary.parent_id = parent_message.id
    left join cms_messages as last_reply_message on last_reply_message.id = reply_summary.last_reply_id
where
    parent_message.reply = 0 and
    parent_message.active = 1 and
    (parent_message.to like '%,%' or parent_message.to = 'all' or parent_message.from = '{$cms_user['id']}')
order by
    last_datetime desc;

php – 在线程中获取最新的消息的更多相关文章

  1. HTML5实现直播间评论滚动效果的代码

    这篇文章主要介绍了HTML5实现直播间评论滚动效果的代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. 前端监听websocket消息并实时弹出(实例代码)

    这篇文章主要介绍了前端监听websocket消息并实时弹出,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. HTML5之消息通知的使用(Web Notification)

    通知可以说是web中比较常见且重要的功能,私信、在线提问、或者一些在线即时通讯工具我们总是希望第一时间知道对方有了新的反馈。本篇文章主要介绍了HTML5之消息通知的使用(Web Notification),感兴趣的小伙伴们可以参考一下

  4. HTML5中的Web Notification桌面通知功能的实现方法

    这篇文章主要介绍了HTML5中的Web Notification桌面通知功能的实现方法,需要的朋友可以参考下

  5. HTML5仿微信聊天界面、微信朋友圈实例代码

    小编最近开发一个基于html5开发的一个微信聊天前端界面,功能很全面,下面小编给大家分享实例代码,需要的朋友参考下

  6. HTML5的postMessage的使用手册

    HTML5提出了一个新的用来跨域传值的方法,即postMessage,这篇文章主要介绍了HTML5的postMessage的使用手册的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. ios – Testflight无法安装应用程序

    我有几个测试人员注册了testflight并连接了他们的设备……他们有不同的ios型号……但是所有这些都有同样的问题.当他们从“safari”或“testflight”应用程序本身单击应用程序的安装按钮时……达到约90%并出现错误消息…

  8. xcode找不到匹配的配置文件

    我有一个AdhociOS应用程序,它给了我“在xcode6中找不到匹配的配置文件”,我创建了一个Adhoc配置文件,下载它,双击它并在General–Identity下选择了一个团队.但我接着得到了那条消息,并尝试使用“修复问题”按钮没有帮助.在构建设置–供应配置文件–发布我有“自动”.任何人都可以帮助我,我完全迷失了……

  9. ios – Reactive Cocoa – 以编程方式设置文本时不会调用UITextView的rac_textSignal

    我正在实现一个聊天UI,并使用ReactiveCocoa根据用户的类型调整聊天气泡的大小.目前,我正在基于textview的rac_textSignal更新UI的布局.一切都很好–除了一点:当用户发送消息时,我以编程方式清除文本字段:…我是否需要拥有一个持有currentTypedString的Nsstring,并在该字符串更新时驱动UI更改?

  10. ios – 当我关闭应用程序时,我从调试器获得消息:由于信号15而终止

    我怎么能解决这个问题,我不知道这个链接MypreviousproblemaboutCoredata对我的问题有影响吗?当我cmd应用程序的Q时,将出现此消息.Messagefromdebugger:Terminatedduetosignal15如果谁知道我以前的问题的解决方案,请告诉我.解决方法>来自调试器的消息:每当用户通过CMD-Q(退出)或STOP手动终止应用程序(无论是在iOS模拟器中还是

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部