我为小型CRM系统进行了数据库设计。它由公司和会议(以及其他)组成。
公司有以下领域: ID(主要,auto_inc) 姓名(文字)
会议有以下领域: ID(主要,auto_inc) CompanyId(链接到Companies.ID) WhenTime(日期时间,会议时存储) 备注(关于会议的文字)
我想要完成的是一个查询,它给出了所有公司的列表(表中的所有字段),以及与该公司的最新会议的WhenTime和Notes(最新是max(WhenTime),如果有的话)是没有,NULL会很好。
我想我可以用游标解决这个问题,但我害怕速度。
我尝试了几种Group By配方,但我担心我缺乏必要的技巧。
我的最后一次尝试是:
select Companies.ID, Companies.name, mts.whentime, mts.notes
from Companies
left outer join (
select top(1) *
from Meetings
order by [whentime] desc
) mts
on Companies.ID = mts.companyID
order by Companies.name asc
但是这段代码只从Meetings中获取一个元组,而不是每个公司中的一个元组,所以这没有用。
有什么想法吗?
答案 0 :(得分:2)
尝试:
select Companies.ID, Companies.name, mts.whentime, mts.notes
from Companies
cross apply
(
select top(1) *
from Meetings
where Companies.ID = Meetings.companyID
order by [whentime] desc
) mts
order by Companies.name asc;
答案 1 :(得分:2)
我首先要创建最新会议的视图,因为我发现创建视图使复杂查询更易于阅读和维护,并且可以引入可重用性元素(如果正确完成)。
CREATE VIEW [dbo].[LatestCompanyNotes]
AS
SELECT [CompanyId], [WhenTime], [Notes]
FROM [Meetings] AS M1
INNER JOIN
(
SELECT [CompanyId], MAX([Id]) AS [MaxId]
FROM [Meetings]
GROUP BY [CompanyId]
) AS M2 ON M2.[CompanyId] = M1.[CompanyId] AND M2.[MaxId] = M1.[Id]
现在,您应该可以像以前一样在查询中加入此视图。
SELECT Companies.[ID], Companies.[Name], mts.[WhenTime], mts.[Notes]
FROM [Companies]
LEFT OUTER JOIN [dbo].[LatestCompanyNotes] AS mts ON mts.[CompanyId] = Companies.[ID]
ORDER BY Companies.[Name] ASC
请注意,我没有测试过代码(我甚至没有安装SQL Server),可能需要进行一些小的更改才能正常工作。
答案 2 :(得分:1)
您不需要在此处进行交叉申请,只需要相关的子查询来查找最近的会议日期:
SELECT Companies.ID, Companies.name, mts.whentime, mts.notes
FROM Companies
LEFT OUTER JOIN Meetings mts
ON Companies.ID = mts.companyID
AND mts.WhenTime =
(SELECT MAX(WhenTime) FROM Meetings mtshist WHERE mtshist.companyID = mts.companyID)
ORDER BY Companies.name
请注意,这将检索所有公司,包括那些从未开过会议的公司:
1 Alexander and co. 2010-01-04 some more notes 2 Barnard Partnership 2010-01-03 NULL 3 Collingwood Ltd. 2010-01-07 recent meeting 4 Dimitri and sons NULL NULL