2016-09-16 14 views
0

私は基本的な履歴を保存するDBテーブルを持っています。私はそれをスーパージェネリックにしています。MS SQLの条件付き結合

表は次のようになります。私は疑問に思って何

HistoryID Action  Table  PrimaryKey Field   OldValue NewValue   User    DateTime 
-------------------------------------------------------------------------------------------------------------------------------------------- 
240233  Added  QueueItem 17177  QueueItemID  17177       XXXXXXXXXXXXXXX 2016-09-16 08:38:58.060 
240237  Modified QueueItem 17177  StatusTypeID 1   2     XXXXXXXXXXXXXXX 2016-09-16 08:38:59.163 
240240  Modified QueueItem 17177  StatusTypeID 2   3     XXXXXXXXXXXXXXX 2016-09-16 08:39:00.850 
240241  Modified QueueItem 17177  PackageID  0        XXXXXXXXXXXXXXX 2016-09-16 08:39:00.850 
240249  Modified QueueItem 17177  StatusTypeID 3   4     XXXXXXXXXXXXXXX 2016-09-16 08:39:09.207 
240256  Modified QueueItem 17177  StatusTypeID 4   5     XXXXXXXXXXXXXXX 2016-09-16 08:39:10.163 
240257  Modified QueueItem 17177  OutputDateTime    9/16/2016 8:39:10 XXXXXXXXXXXXXXX 2016-09-16 08:39:10.163 

することは可能であるが、条件付きでFieldの値に応じて参加することです。私はちょっと立ち往生していますが、t-SQLを使わなければならないと思います。

フィールド上のどこかで個々の選択を行い、すべての結果を結合できますが、より良い方法があるかどうかはわかりませんでしたか?

擬似コードのようなものになるだろう

select h.*, s.[name] from history h 
    some kind of condition that when satified joins the statusType table and if not, then perhaps sets s.[name] to null 

私はこのような何かを試してみました、そしてそれはStatusTo 'で「StatusFrom」の作品ではなく - それは最後の行に日付を変換することはできませんので、失敗しましたintに。

select h.*, 
     so.[Name] as StatusFrom, 
     sn.[Name] as StatusTo 
from history h 
left outer join StatusType so 
      on so.StatusTypeID = Convert(int, h.OldValue) 
      AND 1 = case WHEN h.field = 'StatusTypeID' 
         THEN 1 
         else 0 
        end 
left outer join StatusType sn 
      on sn.StatusTypeID = Convert(int, h.NewValue) 
      AND 1 = case WHEN h.field = 'StatusTypeID' 
         THEN 1 
         else 0 
        end 
where primarykey = 17177 

私はちょうどスーパースタックになっていますが、私はより多くのコード例を提供します。

条件が満たされた場合、私は本当に実際の結合がほしいと思うでしょう。これは可能なのでしょうか?

更新

期待される結果は、次のようになりますSWEの答えは1

HistoryID Action  Table  PrimaryKey Field   OldValue NewValue   User    DateTime    StatusFrom  StatusTo 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
240233  Added  QueueItem 17177  QueueItemID  17177       XXXXXXXXXXXXXXX 2016-09-16 08:38:58.060  NULL   NULL 
240237  Modified QueueItem 17177  StatusTypeID 1   2     XXXXXXXXXXXXXXX 2016-09-16 08:38:59.163  New    Building 
240240  Modified QueueItem 17177  StatusTypeID 2   3     XXXXXXXXXXXXXXX 2016-09-16 08:39:00.850  Building  Ready 
240241  Modified QueueItem 17177  PackageID  0        XXXXXXXXXXXXXXX 2016-09-16 08:39:00.850  NULL   NULL 
240249  Modified QueueItem 17177  StatusTypeID 3   4     XXXXXXXXXXXXXXX 2016-09-16 08:39:09.207  Ready   Processing 
240256  Modified QueueItem 17177  StatusTypeID 4   5     XXXXXXXXXXXXXXX 2016-09-16 08:39:10.163  Processing  Done 
240257  Modified QueueItem 17177  OutputDateTime    9/16/2016 8:39:10 XXXXXXXXXXXXXXX 2016-09-16 08:39:10.163  NULL   NULL 

、私もこれを試してみました:

select h.*, so.[Name] as StatusFrom, sn.[Name] as StatusTo from history h 
    left outer JOIN StatusType so on so.StatusTypeID = Convert(int, h.NewValue) and h.field = 'statustypeid' 
    left outer JOIN StatusType sn on sn.StatusTypeID = Convert(int, h.NewValue) and h.field = 'statustypeid' 
where primarykey = 17177 

を、私は同じ問題を取得する - それがヒットしたときに転倒しますnewValueフィールドの日付

+0

は、条件がすべてのレコードを除外だけそれらがnullことはありません、あなたに参加します。それはあなたが望む/期待したものですか? – GuidoG

+0

はい。すべての履歴を取り戻す必要がありますが、statusTypeのフィールドがある場合は、ステータステーブルに参加してテキスト名を取得します。 – Darren

+0

申し訳ありませんが、私は期待どおりの結果を見ません。 –

答えて

0

Joinin動的テーブルへのgはサポートされていません。

いくつかのcursour-logicを使用してtsql-stored-procedureを実行し、手作業で結果セットを構築する必要があります。

または可能な限り多くのテーブルがある場合は、各テーブルに「参加」したい場合は、誰もが参加して真と評価される条件を設定します。あなただけのいくつかの子テーブルの一つの値が欲しい場合

SELECT * 
FROM a 
LEFT JOIN b on a.id = b.id AND a.table = 'b' and a.field = 'id' 
LEFT JOIN b on a.id = b.something AND a.table = 'b' and a.field = 'something' 
LEFT JOIN c... 

たぶん、SELECT文での副選択のいくつかの種類は、より良く、より読みやすいです。

+0

あなたの 'Or'ステートメントを参考にしてください - これは私の例でやったことです。私は新しいコードを表示したアップデートを追加しました。同じエラーが表示されます – Darren

0

私は非常に私の最初のスクリプトに近いです。 Can I use CASE statement in a JOIN condition?は私が私に私の期待される結果を与えるこの、思い付くすることができ、この答えから

ヘルプ:あなたは左をやっているので、

select h.*, so.[Name] as StatusFrom, sn.[Name] as statusto from history h 
    left outer join StatusType so 
     on 
     case 
     when h.field='StatusTypeID' and so.StatusTypeID = Convert(int, h.OldValue) then 1 
     else 0 
     end = 1 
    left outer join StatusType sn 
     on case 
     when h.field='StatusTypeID' and sn.StatusTypeID = Convert(int, h.NewValue) then 1 
     else 0 
     end = 1 
where primarykey = 17177 
+0

あなたの問題を解決すれば、他の人は既に解決済みですので、それをマークしてください。 –

+0

ありがとう、私は自分の答えを記入するまで2日待たなければならない。 – Darren