4

我有一张桌子 vwuser。我想用表值函数 fnuserrank(userID) 加入这个表。所以我需要与表值函数交叉应用:

SELECT *
FROM vwuser AS a
CROSS APPLY fnuserrank(a.userid)

对于每个用户 ID,它会生成多条记录。我只想要每个没有 Term(inated) Rank 的 empid 的最后一条记录。我怎样才能做到这一点?

数据:

HistoryID empid Rank MonitorDate
1 A1 E1 2012-8-9
2 A1 E2 2012-9-12
3 A1 学期 2012-10-13
4 A2 E3 2011-10-09
5 A2 学期 2012-11-9

必须从该第 2 条记录和第 4 条记录中选择。

4

2 回答 2

3

在 SQL Server 2005+ 中,您可以使用此公用表表达式 ( CTE ) 来确定 MonitorDate 的最新记录,该记录不具有“术语”等级:

WITH EmployeeData AS
(
   SELECT *
      , ROW_NUMBER() OVER (PARTITION BY empId, ORDER BY MonitorDate DESC) AS RowNumber
   FROM vwuser AS a
   CROSS APPLY fnuserrank(a.userid)
   WHERE Rank != 'Term'
)
SELECT *
FROM EmployeeData AS ed
WHERE ed.RowNumber = 1;

注意:此 CTE 之前的语句需要以分号结尾。正因为如此,我看到很多人这样写;WITH EmployeeData AS...

于 2012-10-21T01:09:13.990 回答
2

你必须玩这个。无法在 sqlfiddle 上模拟您的架构。

Select bar.*
from 
(
SELECT *
FROM vwuser AS a
CROSS APPLY fnuserrank(a.userid)
where rank != 'TERM'
) foo
left join 
(
SELECT *
FROM vwuser AS b
CROSS APPLY fnuserrank(b.userid)
where rank != 'TERM'
) bar
on foo.empId = bar.empId
  and foo.MonitorDate > bar.MonitorDate
where bar.empid is null

我总是需要在日期较高时测试左外线。它的工作方式是你做一个左外层。每一行除了每个用户有一个具有更高监控日期的行。那一排就是你想要的那一排。我通常使用我的代码中的一个示例,但我在错误的笔记本电脑上。要让它工作,你可以选择 foo. , 酒吧。并查看结果并找出您想要的行并使条件正确。

你也可以这样做,这样更容易记住

SELECT *
FROM vwuser AS a
CROSS APPLY fnuserrank(a.userid)
) foo
join 
(
select empid, max(monitordate) maxdate
FROM vwuser AS b
CROSS APPLY fnuserrank(b.userid)
 where rank != 'TERM'
) bar
on foo.empid = bar.empid
and foo.monitordate = bar.maxdate

我通常更喜欢使用基于集合的逻辑而不是聚合函数,但无论如何都可以。您还可以通过将 TVF 连接的结果缓存到表变量中来调整它。

编辑: http ://www.sqlfiddle.com/#!3/613e4/ 17 - 我在这里模拟了你的 TVF。显然 sqlfiddle 不喜欢“去”。

select foo.*, bar.*
from 
(
SELECT f.*
FROM vwuser AS a
join fnuserrank f
  on a.empid = f.empid
where rank != 'TERM'
) foo
left join 
(
SELECT f1.empid [barempid], f1.monitordate [barmonitordate]
FROM vwuser AS b
join fnuserrank f1
  on b.empid = f1.empid
where rank != 'TERM'
) bar
on foo.empId = bar.barempid
  and foo.MonitorDate > bar.barmonitordate
where bar.barempid is  null  
于 2012-10-21T01:23:00.040 回答