我有一个名为StatementSummary的表。
SELECT *
FROM StatementSummary
WHERE AccountID = 1234
结果
StatementId StatementDate AccountId AmountDue
-------------------------------------------------
100 2017-10-16 1234 600
99 2017-09-16 1234 500
98 2017-08-16 1234 400
我有另一个表有一个帐户列表。我试图给出显示每个帐户的最后一个AmountDue
的结果
我的代码:
SELECT
AccountID,
(SELECT MAX(StatementDate)
FROM StatementSummary
GROUP BY AccountID) LastStatementDate,
AmountDue
FROM
Accounts A
INNER JOIN
StatementSummary S ON A.AccountId = S.AccountId
基本上,我想显示每个AccountId
的最后一个语句的所有细节。
在row number
and left join
上派生表 - 显示所有账户,无论是否有声明
select *
from
(select row_number() over (partition by accountid order by statementdate desc) rn,
accountid, statementdate,amount
from statementtable
) l
left outer join accountstable a
on l.accountid = a.accountid
And l.rn = 1
在这种情况下,您可以使用SQL Server窗口函数。
SELECT DISTINCT
a.AccountId,
FIRST_VALUE(s.StatementDate) OVER (PARTITION BY s.AccountId ORDER BY s.StatementDate DESC) As LastStatementDate,
FIRST_VALUE(s.AmountDue) OVER (PARTITION BY s.AccountId ORDER BY s.StatementDate DESC) As LastAmountDue
FROM Accounts a
INNER JOIN StatementSummary s
ON a.AccountId = s.AccountId
基本上会发生什么是OVER子句在您的数据中创建分区,在这种情况下,由帐号创建(这些分区是窗口)。然后我们告诉SQL Server按语句日期降序排列每个分区内的数据,因此最后一个语句将位于分区的顶部,然后FIRST_VALUE函数用于抓取第一行。
最后,由于您对两个表之间的每个帐户/语句组合执行此操作,您需要DISTINCT说您只想为每个帐户创建每行的一个副本。
您可以使用SQL Server中的窗口函数执行许多有用的操作。本文对它们进行了很好的介绍:https://www.red-gate.com/simple-talk/sql/learn-sql-server/window-functions-in-sql-server/
这听起来像是我在T-SQL中横向连接又名cross apply
的工作。
SELECT a.*, last_ss.*
FROM Accounts A
cross apply (
select top 1 *
from StatementSummary S ON A.AccountId = S.AccountId
order by StatementDate desc
) last_ss
或者,您可以使用CTE获取帐户的最后日期:
; with l as (
select accountid, max(StatementDate)
from StatementSummary
group by accountid
)
select ...
from Accounts a
inner join l on l.accountid = a.accountid
inner join StatementSummary ss on ss.accountid = a.accountid
and l.StatementDate = ss.StatementDate