web-dev-qa-db-ja.com

データベースから各グループの最後のレコードを取得する-SQL Server 2005/2008

探している結果が得られないようで、いくつかの検索を実行しました。基本的に、会社全体で4つの異なる管理システムが導入されており、私は各システムからのすべてのデータを定期的に組み合わせるプロセスを行っています。私の目標は、1時間ごとに中央データベースにデータを更新することです。これが私が作業しているサンプルデータセットです:

COMPUTERNAME | SERIALNUMBER | USERNAME | LASTIP | LASTUPDATE | SOURCE
TEST1 | 1111 | BOB | 1.1.1.1 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST1 | 1111 | BOB | 1.1.1.1 | 1/18/2011 01:00:00 | MGMT_SYSTEM_2
TEST1 | 1111 | PETER | 1.1.1.11 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST2 | 2222 | GEORGE | 1.1.1.2 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST3 | 3333 | TOM | 1.1.1.3 | 1/19/2011 01:00:00 | MGMT_SYSTEM_2
TEST4 | 4444 | MIKE   | 1.1.1.4 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST4 | 4444 | MIKE   | 1.1.1.41 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST5 | 5555 | SUSIE  | 1.1.1.5 | 1/19/2011 01:00:00 | MGMT_SYSTEM_1

そのため、このマスターテーブルにクエリを実行し、最新のレコード(LASTUPDATEに基づく)のみを取得して、そのシステムに関する最新の情報を取得したいと考えています。問題は、1つのシステムが各データベースに存在する可能性があることですが、もちろん、それらが同じ正確な更新時間を持つことは決してありません。

私はこのようなものを得ると期待します:

TEST1 | 1111 | PETER | 1.1.1.11 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST2 | 2222 | GEORGE | 1.1.1.2 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST3 | 3333 | TOM | 1.1.1.3 | 1/19/2011 01:00:00 | MGMT_SYSTEM_2
TEST4 | 4444 | MIKE   | 1.1.1.41 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST5 | 5555 | SUSIE  | 1.1.1.5 | 1/19/2011 01:00:00 | MGMT_SYSTEM_1

MAX関数を使用してみましたが、1つの列しか取得できません。そして、最後に更新されたレコードを取得する一意のIDフィールドがないため、サブクエリでそれを使用することはできません。システムの1つはMySQLデータベースであり、MySQLのMAX関数は実際にはGROUP BYごとに1つのレコードのみを返すように機能しますが、SQL Serverでは機能しません。

MAXとLEFT JOINを使用する必要があると思っていますが、これまでのところ失敗しました。

あなたの助けをいただければ幸いです。私は過去3〜4時間、実用的なクエリを取得しようとして頭を悩ませてきました。このマスターテーブルは、SQL Server 2005サーバーにあります。

ありがとう!

27
RyanF
;with cteRowNumber as (
    select COMPUTERNAME, SERIALNUMBER, USERNAME, LASTIP, LASTUPDATE, SOURCE,
           row_number() over(partition by COMPUTERNAME order by LASTUPDATE desc) as RowNum
        from YourTable
)
select COMPUTERNAME, SERIALNUMBER, USERNAME, LASTIP, LASTUPDATE, SOURCE
    from cteRowNumber
    where RowNum = 1
57
Joe Stefanelli

SQL Serverでは、最もパフォーマンスの高いソリューションは多くの場合、相関サブクエリです。

_select t.*
from t
where t.lastupdate = (select max(t2.lastupdate)
                      from t t2
                      where t2.computername = t.computername
                     );
_

特に、これは_(computername, lastupdate)_のインデックスを利用できます。概念的には、これがrow_number()より高速である理由は、このクエリが一致しない行を単に除外するためです。 row_number()バージョンは、フィルタリングする前に、すべての行の行番号にアタッチする必要があります-つまり、より多くのデータ処理です​​。

11
Gordon Linoff