2016-06-17 13 views
0

SQL Server 2008でこのビューを作成するのは本当に苦労しています。複数の結合私は頭を抱くことに問題はありませんが、今度は必要なデータを取得するための最良の方法は不明です。SQL Server 2008 Join、Union、Multiple Selects?

私は、「バージョン」という1つのテーブルを持ちます。このテーブルには、JobNumber、バージョン番号、DateCreated、CreatedBy、ステータスおよび説明を含む列があります。

これらの列はすべて結果に返されます。

次に、それはよりトリッキーになります。

"Equipment"という別のテーブルがあります。そのテーブルには、3つのカラムがあります。これらのカラムは、「バージョン」テーブルと相互参照したいものです。これらの列は、ModifiedVersion、ModifiedDate、およびModifiedByです。私がする必要があるのは、行が変更された最後の日付を見つけて、それを前の表のバージョン番号と同じ行に戻すことです。

ので、最終的な結果は次のようになります。

<table border="1"> 
 
    <tr> 
 
    <td>Job Number</td> 
 
    <td>Version</td> 
 
    <td>Date Created</td> 
 
    <td>Created By</td> 
 
    <td>Last Modified</td> 
 
    <td>Last Modified By</td> 
 
    </tr> 
 
    <tr> 
 
    <td>123</td> 
 
    <td>1.00</td> 
 
    <td>01-01-2016</td> 
 
    <td>User 12</td> 
 
    <td>31-01-2016</td> 
 
    <td>User 16</td> 
 
    </tr> 
 
    <tr> 
 
    <td>123</td> 
 
    <td>2.00</td> 
 
    <td>21-03-2016</td> 
 
    <td>User 8</td> 
 
    <td>15-06-2016</td> 
 
    <td>User 11</td> 
 
    </tr> 
 
<tr> 
 
    <td>456</td> 
 
    <td>1.00</td> 
 
    <td>01-01-2016</td> 
 
    <td>User 12</td> 
 
    <td>31-01-2016</td> 
 
    <td>User 16</td> 
 
    </tr> 
 
    <tr> 
 
    <td>456</td> 
 
    <td>2.00</td> 
 
    <td>21-03-2016</td> 
 
    <td>User 8</td> 
 
    <td>15-06-2016</td> 
 
    <td>User 11</td> 
 
    </tr> 
 
    <tr> 
 
    <td>456</td> 
 
    <td>3.00</td> 
 
    <td>01-04-2016</td> 
 
    <td>User 8</td> 
 
    <td>NULL</td> 
 
    <td>NULL</td> 
 
    </tr> 
 
    </table>

だから、問題は、私がいることが、相互参照(「MAX」私が知っているを使用して簡単に十分な)最終更新日付が選択行う方法ですバージョン表のバージョン番号を使用します。

バージョンテーブルと機器テーブルの両方には、それらの間にジョインを必要とする「JobNumber」列があります。

最後に、CreatedBy列とModifiedBy列の結合を行い、ユーザー表に保持されているユーザーの実際の名前を表示します。

私は派生テーブルとさまざまな結合を使って遊んだことがありますが、私はかなり近づくことができますが、異なるユーザーが変更を行ったときや変更が加えられていないときに問題が発生します。変更が加えられていない場合は、NULL値を結果に含めることができます。これは、間違っているように思われるModifiedBy列のグループ化です。

私が得ることができる最も近い、このようなものです:

SELECT  
    dbo.t_ProjectEquipmentVersions.ID, 
    dbo.t_ProjectEquipmentVersions.JobNumber, 
    dbo.t_ProjectEquipmentVersions.VersionNumber, 
    dbo.t_ProjectEquipmentVersions.DateCreated, 
    dbo.t_ProjectEquipmentVersions.CreatedBy,  
    dbo.t_ProjectEquipment.ModifiedVersion, 
    MAX(dbo.t_ProjectEquipment.ModifiedDate) AS LastModifiedDate, 
    dbo.t_ProjectEquipment.ModifiedBy 
FROM   
    dbo.t_ProjectEquipmentVersions 
LEFT OUTER JOIN 
    dbo.t_ProjectEquipment ON dbo.t_ProjectEquipmentVersions.VersionNumber = dbo.t_ProjectEquipment.ModifiedVersion 
GROUP BY 
    dbo.t_ProjectEquipmentVersions.ID, 
    dbo.t_ProjectEquipmentVersions.JobNumber, 
    dbo.t_ProjectEquipmentVersions.VersionNumber, 
    dbo.t_ProjectEquipmentVersions.DateCreated, 
    dbo.t_ProjectEquipmentVersions.CreatedBy, 
    dbo.t_ProjectEquipment.ModifiedVersion, 
    dbo.t_ProjectEquipment.ModifiedBy 

これは近いですが、私は代わりに私が取得したいと思い2の3つの結果行を取得します。これは、modifiedBy列のユーザーIDが異なるためです。私が選択したものから "ModifiedBy"を削除すると、私は後の結果を得ます。

これに関するアドバイス、ヒント、ヘルプは本当に感謝しています。

+0

「ModifiedBy」が複数ある場合は、どちらを表示したいですか? – xdd

+0

最新の修正日に対応するものだけが必要です。 – DA082

+0

それから_Serg_ answerを「OUTER APPLY」で使用するだけで、あなたの必要性に合わせて注文を変更できます。 'order by date' – xdd

答えて

0

使用OUTERが必要な場合加入で

SELECT  
    pev.ID, 
    pev.JobNumber, 
    pev.VersionNumber, 
    pev.DateCreated, 
    pev.CreatedBy,  
    pe.LastModifiedDate, 
    pe.ModifiedBy 
FROM   
    dbo.t_ProjectEquipmentVersions pev 
OUTER APPLY (
    SELECT TOP(1) pe.ModifiedDate AS LastModifiedDate 
     ,pe.ModifiedBy 
    FROM dbo.t_ProjectEquipment pe 
    WHERE pe.ModifiedVersion = pev.VersionNumber 
    ORDER BY ModifiedBy DESC 
) pe 
+0

優秀、とても感謝してくれました! – DA082

+0

最新の変更を得るには、ASCへの日付の順序を変更しなければならなかったのは、TOP 1のためであると推測しました。私が今必要とするのは、ユーザ名をCreatedByカラムとModifiedByカラムに結合してユーザ名を返すことだけです。これらの結合はどこで行われますか? – DA082

+0

クエリの最後に2つのLEFT JOINを追加します – Serg

0
SELECT  
    dbo.t_ProjectEquipmentVersions.ID, 
    dbo.t_ProjectEquipmentVersions.JobNumber, 
    dbo.t_ProjectEquipmentVersions.VersionNumber, 
    dbo.t_ProjectEquipmentVersions.DateCreated, 
    dbo.t_ProjectEquipmentVersions.CreatedBy,  
    dbo.t_ProjectEquipment.ModifiedVersion, 
    dbo.t_ProjectEquipment.ModifiedDate, 
    dbo.t_ProjectEquipment.ModifiedBy 
FROM dbo.t_ProjectEquipmentVersions 
LEFT OUTER JOIN (
       SELECT E1.ModifiedVersion, E2.ModifiedDate, E1.ModifiedBy 
       FROM  t_ProjectEquipment E1 
       INNER JOIN 
        (SELECT ModifiedVersion, MAX(ModifiedDate) AS ModifiedDate 
        FROM dbo.t_ProjectEquipment 
        GROUP BY ModifiedVersion, ModifiedBy 
        ) E2 
       ON E1.ModifiedVersion = E2.ModifiedVersion 
       ) t_ProjectEquipment 

    ON dbo.t_ProjectEquipmentVersions.VersionNumber = t_ProjectEquipment.ModifiedVersion 

使用のJobIdを適用します。