【发布时间】:2013-03-12 17:33:12
【问题描述】:
假设我有一个表 Applications 如下
ApplicationId INT,
CustomerId INT,
ApplicationDate DATETIME,
IsNewCustomer BOOL
我想检索给定日期的应用程序列表以及 IsNewCustomer 标志(如果给定的 CustomerId 没有应用程序,则设置该标志。
目前我在同一张表上使用如下连接
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()
我想知道是否有更好的方法来实现相同的目标,而不必加入同一张桌子,因为它“感觉”不是最优雅的解决方案。
谢谢!
【问题讨论】:
-
你可以做一个子选择而不是加入同一个表,但它可能会花费更多。我不明白为什么你认为它感觉不对。包含您需要查询的信息的表是 Applications 表,那么查询它有什么问题?另一种选择是将 IsNewCustomer 更新为此表中插入/更新过程的一部分,以便在您需要时准备好数据。
-
不,你这样做是正确的。这是使用自联接的正确位置。不要让自我加入让你变得不自觉!
-
如果不对查询进行逆向工程或查看示例数据和所需结果,很难知道,但在 SQL Server 2012 中,使用新的窗口函数可能会有更有效的方法来执行此操作。在早期版本中,这可能是您将要做的最好的事情。表中有多少行?每个客户平均有多少行?
-
除非您有单独的
Customer表进行比较,否则我看不出如何按照您描述的方式设置 IsNewCustomer 标志。 -
感谢你们的 cmets 伙计们,我必须补充一点,我是 SQL 新手,因此不确定“最佳实践”,并认为可能有更优雅的方式来实现这一点。 @tucaz 我同意在插入过程中控制 IsNewCustomer 标志会容易得多,但其他人拥有它,我只是生成报告:)
标签: sql sql-server join