2016-10-13 19 views
0

OK - 最も明確なタイトルではありません。より良く説明するために、ネットワーク上のどのマシンでも死のブルースクリーンが発生していることを示す次の表があります。このクエリ:テーブル1の各レコードの日付より古い、テーブル2の最新レコードで2つのテーブルを結合するにはどうすればよいですか?

SELECT [ID] 
     ,[ServiceTag] 
     ,[BSOD] 
FROM [ITDashboard].[dbo].[tl_login_BSOD] 

は、次のようになります:

ServiceTagは、各マシンのサービスタグであるとBSODブルースクリーンが発生したときのタイムスタンプです

enter image description here

私は、さまざまなデータ(Windowsビルド番号を含む)を記録する別のテーブルを持っています。ビルド番号が変更されるたびに(または興味のある他のフィールド)、新しい行がデータベースに書き込まれます。

私はこのようなマシンごとに最新のタイムスタンプを持つレコードを選択することで、Windowsが私のネットワーク上のマシンの構築を見つけるためにこれを使用することができます

Select w1.machineName 
     ,w1.timestamp 
     ,w1.WindowsBuildNo 
From [ITDashboard].[dbo].[tl_login_whom] As w1 
Inner Join (
    Select machineName 
      ,max(timestamp) as [timestamp] 
    From [ITDashboard].[dbo].[tl_login_whom] 
    Group By machineName) As [q] 
On w1.machineName = q.machineName 
And w1.timestamp = q.timestamp 

この返します

enter image description here

(我々はマシン名としてServiceTagsを使用するようMachineNameにとServiceTagは交換可能です。)

I最初のテーブルを戻すクエリを作成するだけでなく、ブルースクリーンが発生した時点でWindowsビルド番号を表示します

私は次のクエリではほとんど存在しています:

SELECT [ID] 
      ,[ServiceTag] 
      ,[BSOD], 
      WindowsBuildNo 
     FROM [ITDashboard].[dbo].[tl_login_BSOD] b 
     JOIN (
      Select w1.machineName 
       ,w1.timestamp 
       ,w1.WindowsBuildNo 
      From [ITDashboard].[dbo].[tl_login_whom] As w1 
      Inner Join (
       Select machineName 
         ,max(timestamp) as [timestamp] 
       From [ITDashboard].[dbo].[tl_login_whom] 
       Group By machineName) As [q] 
      On w1.machineName = q.machineName 
      And w1.timestamp = q.timestamp 
    ) w on w.machineName = b.serviceTag 

が、これは毎回、最新のビルド番号を戻します。すなわち、ラップトップが1ヵ月前に古いビルド番号にブルースクリーンを表示したが、新しいビルドになった場合は、新しいビルドが常に表示されます。

2番目のクエリから戻す必要があるのは、対応するServiceTag/MachineNameのBSODタイムスタンプよりも新しいという最新のレコードです。

+0

どのDBMSを使用していますか? http://meta.stackoverflow.com/questions/285551/why-may-i-not-upload-images-of-code-on-so-when-asking-a-question/285557#285557 –

+0

サンプルデータを入力してください(イメージではなく)テキストとして、あるいはさらには 'INSERT'ステートメントとして、あなたのテーブルのために。次に、そのサンプルデータに基づいて、最終結果がどのように表示されるかを示します。また、使用するSQL Serverのバージョンのタグを追加します。 –

答えて

1

私はBSODがWindowsマシンを意味するので、SQL Serverも同様です。 ROW_NUMBER()およびPARTITION BYを使用するCTEを使用して、Windowsビルドの変更を含むテーブルを再調整することができます。

WITH _BuildTable AS (
SELECT MachineName 
, WindowsBuild 
, Timestamp 
, ROW_NUMBER() OVER (PARTITION BY MachineName ORDER BY Timestamp ASC) [RowNum] 
FROM build_log_table 
WHERE some_flag_column = "build has changed code" 
) 
, _BuildChanges AS (
SELECT BT1.MachineName 
, BT1.WindowsBuild [BuildComing_From] 
, BT2.WindowsBuild [BuildGoing_To] 
, BT1.Timestamp [BuildTimeStart] 
, CASE (WHEN BT2.TimeStamp IS NULL THEN '20500101' ELSE BT2.TimeStamp END)[BuildTimeEnd] 
FROM _BuildTable AS BT1 
LEFT JOIN _BuildTable AS BT2 ON BT1.MachineName = BT2.MachineName 
AND BT1.RowNum = BT2.RowNum - 1 
) 

SELECT BC.MachineName 
, BC.OldBuild [BSOD_Build] 
, BC.Timestamp 
, BC.[BuildTImeStart] 
, BC.[BuildTImeEnd] 
, BSOD.ID 
, BSOD.ServiceTag 
, BSOD.[BSOD] [TimeStamp] 
FROM BSOD_log_table AS BSOD 
LEFT JOIN _BuildChanges AS BC ON BSOD.ServiceTag = BC.MachineName 
AND BSOD.[TimeStamp] > [BuildTImeStart] AND BSOD.[TimeStamp] < [BuildTImeEnd] 

ビルド変更ロギングテーブルには、行が表す操作の種類を示す列があると考えています。そうでない場合は、クエリは引き続き動作するはずですが、ビルドの変更に関係しない操作のために余分な行が存在するため、最後のクエリにDISTINCT(BC.MachineName)を追加する必要があります。

さらに、マシンのビルド変更が行われていない特別なケースと、現在のビルドでBSODが実行されている特別なケースを処理する必要があります。これが_BuildChangesのCASEステートメントの目的です。

関連する問題