SQL-连接同一个表

SQL-连接同一个表,sql,sql-server,join,Sql,Sql Server,Join,假设我有一个表,如下所示 ApplicationId INT, CustomerId INT, ApplicationDate DATETIME, IsNewCustomer BOOL select o.ApplicationId as ApplicationId, cast(o.ApplicationDate as date) as ApplicationDate, case when n.ApplicationID is not null then 1 else

假设我有一个表,如下所示

ApplicationId INT,
CustomerId INT,
ApplicationDate DATETIME,
IsNewCustomer BOOL
select 
    o.ApplicationId as ApplicationId,
    cast(o.ApplicationDate as date) as ApplicationDate,
    case when n.ApplicationID is not null then 1 else 0 end as IsNewCustomer,
    row_number() over (partition by o.ApplicationId order by o.ApplicationDate desc) as AppSeqNum
from 
    Applications o 
    left join Applications n 
        on n.CustomerId = o.CustomerId
        and n.ApplicationDate < o.ApplicationDate
where
    AppSeqNum = 1
    and ApplicationDate = getdate()
我想检索给定日期的应用程序列表以及IsNewCustomer标志,如果给定CustomerId没有应用程序,则设置该标志

目前,我正在同一个表上使用连接,如下所示

ApplicationId INT,
CustomerId INT,
ApplicationDate DATETIME,
IsNewCustomer BOOL
select 
    o.ApplicationId as ApplicationId,
    cast(o.ApplicationDate as date) as ApplicationDate,
    case when n.ApplicationID is not null then 1 else 0 end as IsNewCustomer,
    row_number() over (partition by o.ApplicationId order by o.ApplicationDate desc) as AppSeqNum
from 
    Applications o 
    left join Applications n 
        on n.CustomerId = o.CustomerId
        and n.ApplicationDate < o.ApplicationDate
where
    AppSeqNum = 1
    and ApplicationDate = getdate()
我想知道是否有更好的方法实现同样的目标,而不必加入到同一个表中,因为它“感觉”不是最优雅的解决方案


谢谢

嗯,您可以使用子查询,但这只会掩盖您的自加入。自联接本身没有什么问题,如果没有正确的索引和约束,并且表大小有限,它们可能会失控。你可能听说过自连接不好的原因之一是在一个连续的单调序列中寻找断点的问题。假设您有1000个值,缺少5个,并且您在value=value+1上执行了一个没有索引或约束的自联接,那么查询优化器可能会在尝试查找5个空匹配之前确定有1000*1000个可能的行。因此,如果你有一个合理的有限的结果集,那么没有问题

您可以进行子选择,而不是加入同一个表,但这可能会花费更多。我不明白你为什么觉得这样不对。保存您需要查询的信息的表是Applications表,那么查询它有什么问题?另一种选择是更新IsNewCustomer,作为此表中插入/更新过程的一部分,以便在需要时准备好数据。不,您这样做是正确的。这是使用自联接的正确位置。不要让自我连接让你变得有自我意识!如果不对查询进行反向工程或查看示例数据和期望的结果,很难知道,但是在SQL Server 2012中,可能有更有效的方法使用新的窗口函数来实现这一点。在早期版本中,这可能是您将要做的最好的。表中有多少行?每个客户平均有多少行?除非您有一个单独的客户表进行比较,否则我不知道如何按照您描述的方式设置IsNewCustomer标志。谢谢您的评论,我必须补充一点,我是SQL的新手,因此不确定“最佳实践”,并认为可能有更优雅的方法来实现这一点@tucaz我同意在插入过程中控制IsNewCustomer标志会容易得多,但它是其他人拥有的,我只是生成报告: