これで遊ぶ必要があります。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
より高い日付で左アウターを常にテストする必要があります。それが機能する方法は、左外側を行うことです。ユーザーごとに 1 つを除くすべての行に、より長い監視日付の行があります。その1行はあなたが望むものです。私は通常、コードの例を使用しますが、間違ったラップトップを使用しています。それを機能させるには、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 は "go" を好まなかったようです。
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