Подзапрос T-SQL на последнюю дату с InnerJoin - PullRequest
0 голосов
/ 29 октября 2011

Я хочу сделать что-то похожее на этого парня: Максимальное количество подзапросов T-SQL (дата) и объединений

Я должен сделать это с отношением n: m.

Итак, макет:

tbl_Opportunity
tbl_Opportunity_tbl_OpportunityData
tbl_OpportunityData

Итак, как вы видите, существует таблица пересечений, которая связывает возможности с данными о возможностях. Для каждой возможности есть несколько данных о возможностях. На мой взгляд, мне нужен только список со всеми возможными вариантами и данными из последних данных о возможностях.

Я пробовал что-то вроде этого:

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

Проблема в том, что мое представление теперь включает строку для данных каждой возможности, поскольку я не знаю, как отфильтровать, что мне нужны только самые последние данные.

Вы можете мне помочь? мое описание проблемы достаточно ясно?

Заранее спасибо :-) с наилучшими пожеланиями, Laurin

Ответы [ 2 ]

1 голос
/ 29 октября 2011
; WITH Base AS (
    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    
)

, OrderedByDate AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY ChangeDate DESC) RN FROM Base
)

SELECT * FROM OrderedByDate WHERE RN = 1

Чтобы сделать его более читабельным, я использую CTE (часть WITH).В конце концов, настоящий «трюк» заключается в ROW_NUMBER() разбиении данных на tbl_Opportunity.Id и упорядочении разделов на ChangeDate DESC (и я называю это RN).Очевидно, что максимальная дата в каждом разделе будет RN = 1, а затем мы отфильтруем ее по RN.

. Без использования CTE это будет примерно так:

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
0 голосов
/ 31 октября 2011

Выражение можно упростить еще на один шаг:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...