2

親テーブルCASESと子テーブルがありますUPDATES。日課CASESは、各行をUPDATESテーブルに記録します。これは、それぞれCASEに 1 つと複数の があることを意味しますUPDATES

ケース

CaseID  | CaseStatus | [other fields]
=====================================
PK(int) | Free text  | Free text...

アップデート

UpdateID | UpdateDate   | CaseID  | CaseStatus | [other fields]
===============================================================
PK(int)  | Date Entered | FK(int) | Free text  | Free text...

次のクエリを使用できます-

select *,
  (Row_Number() over (partition by CaseID order by UpdateDate desc)) as SeqNo
from UPDATES order by SeqNo, CaseId

UPDATES次のように、データをグループ化して#TEMPテーブルに並べます。

SeqNo | UpdateID | UpdateDate  | CaseID | CaseStatus | [other fields]
====================================================================
1     | 9876     | 30-Jun-2013 | 345    | [free text...]
1     | 9875     | 30-Jun-2013 | 789    | [free text...]
2     | 9765     | 29-Jun-2013 | 345    | [free text...]
2     | 9764     | 29-Jun-2013 | 789    | [free text...]
3     | 9654     | 28-Jun-2013 | 345    | [free text...]
4     | 9653     | 27-Jun-2013 | 345    | [free text...]

サードパーティのレポート ライブラリを使用しています。UPDATESのサブコンポーネントとして特定のレポートを有効にするにはCASES、フラットな結果セットとしてデータを返すクエリが必要です。言い換えるとsq2_CaseStatusUPDATES.CaseStatus特定CASECASES. (つまり、CaseIdレポート コードに渡され、レポート コードがストアド プロシージャを実行し、SP がクエリを実行して結果セットを返し、結果セット列のコード キーをレポートしてデータを検索します。)

テーブルから最新の 12 個のSeqNo値 (1 ~ 12)を提示するだけで済みUPDATESます。しかし、メインのレポート クエリ内でこのデータをクエリして返す方法に苦労しています。

質問:表示され、レポート フィールドのプレフィックスとして使用できるように、UPDATESデータをクエリして返す方法は?SeqNo

私の線形思考が当然のことである場合は、事前にお詫び申し上げます...

レポート クエリ内に、他のリンク テーブルからSELECTすべてのデータを取得してデータを選択するステートメントがあります。CASESこの内でSELECT、「ループ」手法を使用して特別な関数を呼び出すことはできますか?

この特別な関数は、カウンター変数 (1 から 12 まで) を取り、その変数を使用してグループ化/シーケンス#TEMPテーブルをクエリし、変数をSeqNo使用して「コード化された」列の下にデータを表示します。CASEしたがって、次のように、12 個の子テーブルがレコードにリンクされることになります。

SeqNo | UpdateID | sq1_UpdateDate  | CaseID | sq1_CaseStatus | sq1_[other fields]
=================================================================================
1     | 9876     | 30-Jun-2013     | 345    | [free text...]
1     | 9875     | 30-Jun-2013     | 789    | [free text...]

SeqNo | UpdateID | sq2_UpdateDate  | CaseID | sq2_CaseStatus | sq2_[other fields]
=================================================================================
2     | 9765     | 29-Jun-2013     | 345    | [free text...]
2     | 9764     | 29-Jun-2013     | 789    | [free text...]

and so on...

これはうまくいくと思います。SELECTしかし、ステートメント内でこのように「ループ」することは可能ですか?

- 実際には、CASESUPDATESテーブルの両方が非常に広いため、単一の#TEMPテーブルを「広げる」オプションを放棄しました (つまり、それぞれの 1 ~ 12SeqNoセットのデータをすべて表示するCaseId)。また、レポート インターフェース コードを変更すると問題が解決する可能性があることも認識していますが、その (費用のかかる) オプションは避けようとしています。

更新/回避策:まあ、#TEMP最初に放棄した単一の「ワイド」テーブルソリューションに頼らなければなりませんでした。再帰スクリプトを使用して、必要なMAXステートメントの長いリストを生成しました。これらは、プレフィックス付きの列名を生成します。INNER JOIN次に、これらをテーブル値関数の (シーケンスを実行する)と組み合わせました。何かのようなもの...

SELECT up.CaseId AS CaseId,
       MAX(CASE sq.SeqNo WHEN 1 THEN up.UpdateDate ELSE '' END) AS sq1_UpdateDate,
       MAX(CASE sq.SeqNo WHEN 2 THEN up.UpdateDate ELSE '' END) AS sq2_UpdateDate,
       ...
       ...<up to sq12_ for all fields>...
       ...
FROM   UPDATES up
INNER JOIN  (
  SELECT UpdateId,
         Row_Number() OVER (PARTITION BY CaseId ORDER BY UpdateDate Desc) AS SeqNo
  FROM   UPDATES ) sq ON sq.UpdateId = up.UpdateId
GROUP BY up.CaseId
4

1 に答える 1

1

それはきれいではありません...しかし、それはうまくいくはずです。

ストアド プロシージャ内で Dynamic Sql を使用して、特定の子行を取得し、その場で名前を作成できます。

##(ただし、これを機能させるには、一時テーブルを使用してグローバル一時テーブルに変更する必要がある場合があります)

CREATE PROCEDURE GetChild @chilSeq int
AS
DECLARE @sChild varchar(10)
set @sChild = convert(varchar(10), @childSeq)
DECLARE @dsql varchar(4000)
set @dsql = 'SELECT SeqNo, UpdateID, [sq'+ @sChild +'_UpdateDate], CaseID, [sq'+ @sChild +'_CaseStatus], [sq'+ @sChild +'_[other fields]]
FROM #temp where SeqNo = ' + @sChild

execute @dsql
GO

私が言ったように、それはきれいではありません。パフォーマンスを考慮して使用することはお勧めしませんが、あなたの状況では、それがあなたが探している解決策かもしれません.

于 2013-07-06T13:06:12.450 に答える