查询查询或带分组的循环

时间:2014-01-24 11:35:22

标签: coldfusion coldfusion-10

我有一个表格,其中包含有关用户之间发送的消息的信息。它看起来像这样:

MessageID | MessageIDReference | MessageSubject   | Body     | Date
1           NULL                 Test               Hello      10/01/2014
2           1                    RE: Test           Goodbye    11/01/2014
3           1                    RE: Test           Hello      11/01/2014
.......
50          45                   RE: Subject        Blah       12/12/2014

因此,创建的第一条消息在NULL列中将具有MessageIDReference值(因为它的新消息不是回复)。当用户回复邮件时,会将MessageID原始邮件插入MessageIDReference列,以便我们知道其回复的邮件。好又简单!

在我的网页上,我想显示对话中的第一条消息,然后是在一个区域内对该消息的任何后续回复,以便轻松查看对话流程,如:

<ol>
<cfloop query="messages">
<li>
  #MessageSubject# #Body#
      <ol>
      <!--- I want replies to this message here somehow --->
      <li>1st reply</li>
      <li>2nd reply</li>
      etc etc
      </ol>
</li>
  </cfloop>
<ol>

我认为可以通过每个<cfloop>标签内的某种类别来完成,但我不确定如何。我现在认为必须在内部循环中使用查询查询来完成它,以便它返回每个MessageID的所有回复并输出它们。

查询查询时我会这样做:

<cfquery name="Messages">
    SELECT * FROM Messages
    </cfquery>

<ol>
  <cfquery type="query" name="MessagesNew">
    SELECT *
    FROM Messages
    WHERE MessageIDReference IS NULL
    </cfquery>
  <cfloop query="MessagesNew">
  <li> #MessagesNew.MessageSubject# #MessagesNew.Body#
    <cfquery type="query" name="MessagesReplies">
    SELECT *
    FROM Messages
    WHERE MessageIDReference = #MessagesNew.MessageID#
    </cfquery>
    <ol>
      <cfloop query="MessagesReplies">
      <li>#MessagesReplies.MessageSubject# #MessagesReplies.Body#</li>
      </cfloop>
    </ol>
  </li>
  </cfloop>
</ol>

2 个答案:

答案 0 :(得分:4)

Dan提出了一个很好的建议,但这里有一个查询可以获取原始邮件以及任何回复 - 排序第一行是原始邮件,其余的都是按时间顺序回复。

<cfquery type="query" name="MessagesReplies">
    SELECT *
    FROM Messages
    WHERE MessageIDReference = <cfqueryparam cf_sql_type="cf_sql_integer" value="#MessagesNew.MessageID#" />
    OR MessageID = <cfqueryparam cf_sql_type="cf_sql_integer" value="#MessagesNew.MessageID#" /> 
    ORDER BY MessageId, date
</cfquery>

您在MessageIDReference为NULL的情况下运行的查询将返回每个线程中的第一条消息,因此您需要根据ID选择该消息。

注意使用cfqueryparam,您应该始终参数化您的查询。总是

答案 1 :(得分:1)

这种方式可能更容易。

<cfquery name = "GetMessages" datasource="something">
select MessageId, ifnull(MessageIDReference, MessageId) Message
, other fields
from your message table
where whatever
order by Message, MessageId

<cfoutput query="GetMessages" group = "message">
#grouped data#
<cfoutput>
 #ungrouped data#
</cfoutput>
</cfoutput>

请注意,ifnull函数是特定于数据库的。您没有指定数据库引擎。如果你使用的任何东西没有相同的功能,你可以使用这个

case when MessageIDReference is not null MessageIDReference
else MessageId end Message

另请注意,您的问题比您想象的要复杂得多。假设您只需要特定日期范围内的数据。如果是这样,您将需要进一步过滤它以仅包括在该日期范围内启动的那些线程。子查询可能会起作用,但我会给你一个机会自己解决这个问题。