4

テーブル vwuser が 1 つあります。このテーブルをテーブル値関数 fnuserrank(userID) と結合したい。したがって、テーブル値関数をクロス適用する必要があります。

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

ユーザー ID ごとに複数のレコードが生成されます。Term(inated) のランクを持たない各 empid の最後のレコードのみが必要です。これどうやってするの?

データ:

HistoryID empid ランク 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 以降では、この Common Table Expression ( CTE ) を使用して、「Term」のランクを持たない 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

より高い日付で左アウターを常にテストする必要があります。それが機能する方法は、左外側を行うことです。ユーザーごとに 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  
于 2012-10-21T01:23:00.040 に答える