Tsql 具有InnerJoin的最新日期的T-SQL子查询

Tsql 具有InnerJoin的最新日期的T-SQL子查询,tsql,Tsql,我想做一件类似的事情,比如这个家伙: 我必须用n:m关系来做这件事 因此,布局是: tbl_Opportunity tbl_Opportunity_tbl_OpportunityData tbl_OpportunityData 如您所见,有一个连接opportunity和opportunitydata的交叉表。 对于每个opportunity,都有多个opportunity数据。在我看来,我只想要一份包含所有Opportunite和最新opportunity数据的列表 我试过这样的方法: S

我想做一件类似的事情,比如这个家伙:

我必须用n:m关系来做这件事

因此,布局是:

tbl_Opportunity
tbl_Opportunity_tbl_OpportunityData
tbl_OpportunityData
如您所见,有一个连接opportunity和opportunitydata的交叉表。 对于每个opportunity,都有多个opportunity数据。在我看来,我只想要一份包含所有Opportunite和最新opportunity数据的列表

我试过这样的方法:

SELECT     
    dbo.tbl_Opportunity.Id, dbo.tbl_Opportunity.Subject, 
    dbo.tbl_User.UserName AS Responsible, dbo.tbl_Contact.Name AS Customer, 
    dbo.tbl_Opportunity.CreationDate, dbo.tbl_Opportunity.ActionDate AS [Planned Closure], 
    dbo.tbl_OpportunityData.Volume, 
    dbo.tbl_OpportunityData.ChangeDate, dbo.tbl_OpportunityData.Chance
FROM         
    dbo.tbl_Opportunity 
INNER JOIN
    dbo.tbl_User ON dbo.tbl_Opportunity.Creator = dbo.tbl_User.Id 
INNER JOIN
    dbo.tbl_Contact ON dbo.tbl_Opportunity.Customer = dbo.tbl_Contact.Id 
INNER JOIN
    dbo.tbl_Opprtnty_tbl_OpprtnityData ON dbo.tbl_Opportunity.Id = dbo.tbl_Opprtnty_tbl_OpprtnityData.Id 
INNER JOIN
    dbo.tbl_OpportunityData ON dbo.tbl_Opprtnty_tbl_OpprtnityData.Id2 = dbo.tbl_OpportunityData.Id
SELECT * FROM (
    SELECT     dbo.tbl_Opportunity.Id, dbo.tbl_Opportunity.Subject, dbo.tbl_User.UserName AS Responsible, dbo.tbl_Contact.Name AS Customer, 
                      dbo.tbl_Opportunity.CreationDate, dbo.tbl_Opportunity.ActionDate AS [Planned Closure], dbo.tbl_OpportunityData.Volume, 
                      dbo.tbl_OpportunityData.ChangeDate, dbo.tbl_OpportunityData.Chance,
                      ROW_NUMBER() OVER (PARTITION BY dbo.tbl_Opportunity.Id ORDER BY dbo.tbl_OpportunityData.ChangeDate DESC) RN
    FROM         dbo.tbl_Opportunity INNER JOIN
                      dbo.tbl_User ON dbo.tbl_Opportunity.Creator = dbo.tbl_User.Id INNER JOIN
                      dbo.tbl_Contact ON dbo.tbl_Opportunity.Customer = dbo.tbl_Contact.Id INNER JOIN
                      dbo.tbl_Opprtnty_tbl_OpprtnityData ON dbo.tbl_Opportunity.Id = dbo.tbl_Opprtnty_tbl_OpprtnityData.Id INNER JOIN
                      dbo.tbl_OpportunityData ON dbo.tbl_Opprtnty_tbl_OpprtnityData.Id2 = dbo.tbl_OpportunityData.Id    
) AS Base WHERE RN = 1
问题是我的视图现在包含了每个opportunity数据的一行,因为我不知道如何筛选我只想要最新的数据

你能帮我吗?我的问题描述清楚吗

提前感谢:-) 最美好的祝福, 劳林

为了使它更具可读性,我使用了CTE(带部件)。最后,真正的“诀窍”是使用
ROW\u NUMBER()
tbl\u Opportunity.Id
对数据进行分区,并按
ChangeDate DESC
对分区进行排序(我称之为
RN
)。显然,每个分区中的最大日期将是
RN=1
,然后我们通过
RN
对其进行过滤

如果不使用CTE,它将是这样的:

SELECT     
    dbo.tbl_Opportunity.Id, dbo.tbl_Opportunity.Subject, 
    dbo.tbl_User.UserName AS Responsible, dbo.tbl_Contact.Name AS Customer, 
    dbo.tbl_Opportunity.CreationDate, dbo.tbl_Opportunity.ActionDate AS [Planned Closure], 
    dbo.tbl_OpportunityData.Volume, 
    dbo.tbl_OpportunityData.ChangeDate, dbo.tbl_OpportunityData.Chance
FROM         
    dbo.tbl_Opportunity 
INNER JOIN
    dbo.tbl_User ON dbo.tbl_Opportunity.Creator = dbo.tbl_User.Id 
INNER JOIN
    dbo.tbl_Contact ON dbo.tbl_Opportunity.Customer = dbo.tbl_Contact.Id 
INNER JOIN
    dbo.tbl_Opprtnty_tbl_OpprtnityData ON dbo.tbl_Opportunity.Id = dbo.tbl_Opprtnty_tbl_OpprtnityData.Id 
INNER JOIN
    dbo.tbl_OpportunityData ON dbo.tbl_Opprtnty_tbl_OpprtnityData.Id2 = dbo.tbl_OpportunityData.Id
SELECT * FROM (
    SELECT     dbo.tbl_Opportunity.Id, dbo.tbl_Opportunity.Subject, dbo.tbl_User.UserName AS Responsible, dbo.tbl_Contact.Name AS Customer, 
                      dbo.tbl_Opportunity.CreationDate, dbo.tbl_Opportunity.ActionDate AS [Planned Closure], dbo.tbl_OpportunityData.Volume, 
                      dbo.tbl_OpportunityData.ChangeDate, dbo.tbl_OpportunityData.Chance,
                      ROW_NUMBER() OVER (PARTITION BY dbo.tbl_Opportunity.Id ORDER BY dbo.tbl_OpportunityData.ChangeDate DESC) RN
    FROM         dbo.tbl_Opportunity INNER JOIN
                      dbo.tbl_User ON dbo.tbl_Opportunity.Creator = dbo.tbl_User.Id INNER JOIN
                      dbo.tbl_Contact ON dbo.tbl_Opportunity.Customer = dbo.tbl_Contact.Id INNER JOIN
                      dbo.tbl_Opprtnty_tbl_OpprtnityData ON dbo.tbl_Opportunity.Id = dbo.tbl_Opprtnty_tbl_OpprtnityData.Id INNER JOIN
                      dbo.tbl_OpportunityData ON dbo.tbl_Opprtnty_tbl_OpprtnityData.Id2 = dbo.tbl_OpportunityData.Id    
) AS Base WHERE RN = 1

该语句可以进一步简化:

SELECT TOP 1 WITH TIES
    dbo.tbl_Opportunity.Id, dbo.tbl_Opportunity.Subject, dbo.tbl_User.UserName AS Responsible, 
    dbo.tbl_Contact.Name AS Customer, dbo.tbl_Opportunity.CreationDate, 
    dbo.tbl_Opportunity.ActionDate AS [Planned Closure], dbo.tbl_OpportunityData.Volume, 
    dbo.tbl_OpportunityData.ChangeDate, dbo.tbl_OpportunityData.Chance
FROM 
    dbo.tbl_Opportunity INNER JOIN
    dbo.tbl_User ON dbo.tbl_Opportunity.Creator = dbo.tbl_User.Id INNER JOIN
    dbo.tbl_Contact ON dbo.tbl_Opportunity.Customer = dbo.tbl_Contact.Id INNER JOIN
    dbo.tbl_Opprtnty_tbl_OpprtnityData ON dbo.tbl_Opportunity.Id = dbo.tbl_Opprtnty_tbl_OpprtnityData.Id INNER JOIN
    dbo.tbl_OpportunityData ON dbo.tbl_Opprtnty_tbl_OpprtnityData.Id2 = dbo.tbl_OpportunityData.Id    
ORDER BY 
    ROW_NUMBER() OVER (PARTITION BY dbo.tbl_Opportunity.Id ORDER BY dbo.tbl_OpportunityData.ChangeDate DESC);

我强烈建议使用有意义的表别名,使您的查询更具可读性!我现在完全知道你在做什么……但我印象深刻。它只是工作。我正在努力度过这段时间。也许我还有一些问题要问。但是你能告诉我:有没有一种方法可以在不输出RN的情况下执行此操作?在最后的
SELECT
,而不是
SELECT*
中,您可以对所需的列执行
SELECT
。谢谢,这也很有效。我还有一个问题。我应该过滤掉tbl_Opportunity.m__object_state=0的项目。但是我不能让它工作。我应该在何处插入此where条款?