【问题标题】:Trying to do a "top 1 / order by" in an Inner Join with T-SQL / SQL Server尝试在使用 T-SQL / SQL Server 的内部联接中执行“前 1/排序依据”
【发布时间】:2016-07-19 14:20:17
【问题描述】:

这是我的用例。我正在尝试加入一个特定的表,该表中可以有多个要加入的记录。

所以,这是我的全部查询,我所说的联接是第一个内部联接:

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 值的记录。我希望这是有道理的。我怎样才能做到这一点?

【问题讨论】:

标签: sql sql-server tsql join inner-join


【解决方案1】:

一种方法是使用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 而不是 ap 而不是 b。这使得查询更易于阅读和维护。

【讨论】:

    【解决方案2】:

    您还可以使用 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
    

    【讨论】:

      猜你喜欢
      • 2015-07-24
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 2012-01-28
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 2017-01-01
      相关资源
      最近更新 更多