2014-01-24 78 views
2

我有一張表,用於保存有關用戶之間發送的消息的信息。它看起來是這樣的:查詢查詢或分組循環

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 

所以創建將在MessageIDReferenceNULL值(因爲它是一個新的消息不是回覆)的第一條消息。當用戶回覆郵件時,它會將原始郵件的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> 
+0

您最好不要使新消息的MessageIDReference無效。相反,使其與MessageID相同。這當然會使這個任務更容易。順便說一下,只有只有一條消息沒有引用時,您的查詢樣本查詢纔會有效。 –

+0

@DanBracuk我編輯了我的文章,所以它更清晰一點。我之前在衝,並沒有完成我的例子 –

+0

爲什麼你會急於提問? –

回答

4

丹做一個偉大的建議,但這裏是一個查詢,將工作,以獲得原始消息以及任何答覆 - 分頁,使第一行是原始消息,其餘的都是按時間順序的回覆。

<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,你應該總是參數化你的查詢。總是。

+0

如果messageid字段是自動增量,則可能不需要按日期排序部分。 –

+2

我更喜歡在警告方面出錯:D –

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 

另外請注意,你的問題比你想象的更復雜。假設你只想要某個日期範圍的數據。如果是這樣,您將需要進一步過濾,以僅包含那些在該日期範圍內啓動的線程。一個子查詢可能會起作用,但我會給你一個自己解決的機會。

+1

FWIW,嘗試['coalesce'](http://en.wikipedia.org/wiki/Null_%28SQL%29#COALESCE)以獲得更多的數據庫中立選擇。它不是一個確切的等價物,但是比像'ifnull','isnull'之類的供應商特定功能往往具有更廣泛的支持。 – Leigh