我觉得完全愚蠢。我的sql生锈了。
我有两个表,Message和MessageThread。使用ParentTHreadID作为外键,每条消息属于一个MessageThread。你可能会看到它的发展方向。
好吧,我想做这样的事情。我想从表,消息和线程中获取列,但是消息的datecreated是该线程中的最大值。因此,每条记录都将包含一个消息记录的线程列和列,该消息记录是该消息线程中最新发布的消息记录。
这是我到目前为止获得的所有线程列和消息的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到sql或linq到nhibernate。
谢谢, 克雷格
答案 0 :(得分: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
这应该可以获得包含两个嵌套查询的所有列。
答案 1 :(得分: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)
这具有仅选择一行的效果,该行具有该线程的最大日期。 此外,这意味着您可以选择所需的列,而无需对其进行子查询,从而减少查询必须执行的表扫描或索引扫描的数量。
答案 2 :(得分: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的数据。在这种情况下,只需加入Message。