2016-07-19 2 views
1

Итак, вот мой прецедент. Я пытаюсь присоединиться к определенной таблице, которая может содержать несколько записей в этой таблице.Попытка сделать «топ 1/порядок» во внутреннем соединении с T-SQL/SQL Server

Итак, вот мой запрос в полном объеме, и присоединиться я говорю о является первым внутренним соединением:

select top 1 
    a.IN_Notification_ID, 
    a.DI_Surrogate_ID, 
    a.IN_Ref_Content_ID, 
    a.IN_Name, 
    a.IN_Description, 
    a.IN_Category, 
    a.IN_Rank, 
    a.IN_Publish_Date, 
    a.IN_URL_EN, 
    a.IN_URL_FR, 
    a.IN_URL_NAME_EN, 
    a.IN_URL_NAME_FR, 
    a.IN_HEADER_EN, 
    a.IN_HEADER_FR, 
    a.IN_BODY_EN, 
    a.IN_BODY_FR, 
    a.IN_ACTION_COMPLETE_URL_EN, 
    a.IN_ACTION_COMPLETE_URL_FR, 
    1 as 'IN_COMPLETE', 
    getdate() as 'ET_LAST_MODIFIED_DATE' 
from CXXXXXXX.Important_Notices_Inbox a with (nolock) 
inner join CXXXXXXX.IGO_PROFILES b with (nolock) on a.DI_Surrogate_ID = b.email 
inner join CXXXXXXX.PI_CONTENTVIEWS c on b.[user_id] = c.[user_id] and a.IN_Ref_Content_ID = c.content_id 
where c.[timestamp] > a.[Date_Added] 
order by c.[timestamp] desc 

Итак, первое внутреннее соединение, что вы видите, может и, вероятно, будет возвращать несколько записей (могут быть несколько записей, соответствующих критериям a.DI_Surrogate_ID = b.email). Я хочу идеально выполнить «SELECT TOP 1»/«ORDER BY _CustomObjectKey desc», чтобы ТОЛЬКО присоединиться к записи с «самым высоким» значением _CustomObjectKey. Я надеюсь в этом есть смысл. Как я могу это сделать?

+0

В качестве дополнительной заметки вы можете прочитать эту статью, прежде чем продолжать распространять подсказку NOLOCK во всем мире. http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ –

ответ

2

Один из способов - использовать row_number(). Но в SQL Server вы можете использовать боковое соединение, которое использует ключевое слово apply. Таким образом, пункт from будет выглядеть следующим образом:

from C1397722.Important_Notices_Inbox a with (nolock) cross apply 
    (select top 1 b.* 
     from C1397722.IGO_PROFILES b with (nolock) 
     where a.DI_Surrogate_ID = b.email 
     order by _CustomObjectKey desc 
    ) b inner join 
    CXXXXXXX.PI_CONTENTVIEWS c 
    on b.[user_id] = c.[user_id] and a.IN_Ref_Content_ID = c.content_id 

Примечание: Я бы посоветовал вам использовать таблицы сокращений для псевдонимов столбцов. В вашем случае ini вместо a и p вместо b. Это упрощает чтение и поддержку запроса.

1

Вы также можете использовать функцию ROW_NUMBER() с разделом на DI_Surrogate_ID и заказать _CustomObjectKey desc.

WITH cte_data AS 
(
select top 1 
    a.IN_Notification_ID, 
    a.DI_Surrogate_ID, 
    a.IN_Ref_Content_ID, 
    a.IN_Name, 
    a.IN_Description, 
    a.IN_Category, 
    a.IN_Rank, 
    a.IN_Publish_Date, 
    a.IN_URL_EN, 
    a.IN_URL_FR, 
    a.IN_URL_NAME_EN, 
    a.IN_URL_NAME_FR, 
    a.IN_HEADER_EN, 
    a.IN_HEADER_FR, 
    a.IN_BODY_EN, 
    a.IN_BODY_FR, 
    a.IN_ACTION_COMPLETE_URL_EN, 
    a.IN_ACTION_COMPLETE_URL_FR, 
    1 as 'IN_COMPLETE', 
    getdate() as 'ET_LAST_MODIFIED_DATE', 
    ROW_NUMBER() OVER (PARTITION BY DI_Surrogate_ID order by _CustomObjectKey desc) as rn 
from C1397722.Important_Notices_Inbox a with (nolock) 
inner join C1397722.IGO_PROFILES b with (nolock) on a.DI_Surrogate_ID = b.email 
inner join CXXXXXXX.PI_CONTENTVIEWS c on b.[user_id] = c.[user_id] and a.IN_Ref_Content_ID = c.content_id 
where c.[timestamp] > a.[Date_Added] 
order by c.[timestamp] desc 
) 
SELECT * from cte_data where rn = 1 
Смежные вопросы