2010-04-13 169 views
1

我感覺完全愚蠢。我生我的sql。SQL Group By and Join

我有兩個表,Message和MessageThread。每條消息都屬於一個使用ParentTHreadID作爲外鍵的MessageThread。你可能會看到這是怎麼回事。

嗯,我想要做這樣的事情。我想從兩個表,消息和線程中獲取列,但創建的消息的date是該線程中的最大值。因此,每條記錄都將包含該消息線程中最近發佈的一條消息記錄的線程列和列。

這是我到目前爲止所得到的所有線程列和消息的ID。它的工作原理,但使用子查詢,我不得不做一堆其他子查詢來獲得其他列。呸。

select t.*, (select top 1 m.ID from Message m where m.ParentThreadID = t.ID order by DateCreated desc) as MessageID
from MessageThread t

獎勵積分的人誰不能只給我的SQL,但是的LINQ to SQL或LINQ到NHibernate的。

謝謝, 克雷格

回答

0

解決辦法:更多的子查詢!

select * from (
    select t.*, (
     select top 1 ID 
     from Message 
     where ParentThreadID = t.ID 
     order by DateCreated desc 
    ) as MessageID 
    from MessageThread t 
) tm 
    left join Message m on tm.MessageID = m.ID 

這應該讓你有兩個嵌套查詢的所有列。

+0

我認爲這在linq中是不可能的? – fregas 2010-04-13 21:43:09

+0

可能不是,但我真的不是流利的linq。 – Blorgbeard 2010-04-13 22:52:43

0

如何將這項工作對您:

SELECT (whateverYouWant) 
FROM Message m, MessageThread mt 
WHERE m.ParentThreadID = mt.ID 
AND mt.DateCreated = (SELECT MAX(mt2.DateCreated) 
         FROM MessageThread mt2 
         WHERE mt2.ID= mt.ID) 

這有隻選擇一列,這對於該線程的最大日一個的效果。 此外,它意味着你可以選擇你想要的任何列而不必對它們進行子查詢,從而減少查詢必須執行的表掃描或索引掃描的次數。

0

首先,你可以(在你的OP)通過使用子查詢,像這樣寫這篇文章沒有派生表:

Select ... 
From MessageThread As T 
Where Id = (
      Select TOP 1 M.Id 
      From Message As M 
      Where M.ParentThreadId = T.Id 
      Order By DateCreated Desc 
      ) 

等效LINQ會是這樣的:

var query = from messageThread in MessageThread 
       join message in Message on message.ParentThreadId == messageThread.Id 
       let first = (messages.Where(m => m.ParentThreadId == messageThread.Id).OrderByDescendng(m => m.DateCreated).First().Id) 
       where messageThread.Id == first 
       select new {MessageThread = messageThread, Message = Message}; 

編輯你提到你也需要消息中的數據。在這種情況下,只需加入Message。

+0

我需要messagethread和消息,但消息需要是該線程中最近的1條消息。 所以我需要像選擇新的{messageThread,消息}某處 – fregas 2010-04-14 19:35:26

+0

@fregas - 如果是這樣的話,那麼只需加入到消息。 – Thomas 2010-04-14 19:44:36