顧客の注文を「レベル」(シルバー、ゴールドなど)に関連付ける必要があります注文時:
CRM server::CRM db::CRM table
----------
CustomerID PreviousLevel NewLevel NewLevelGrantedOn
Order server::Order db::Order table
----------
OrderID CustomerID OrderPlacedOn
SSISパッケージで、私はこれを行いました。
select top 1 * where CustomerID = ? and LevelGrantedOn < ? order by LevelGrantedOn desc
CRMデータベースからデータを抽出し(両方のパラメーターはステップ1から取得)、いくつかの列を派生させ、出力を別のテーブルに書き込みます。Dbの順序には2万を超えるレコードがあります。これは、データフロータスクが2万回を超えて実行されることを意味します。 CRMデータベースも2万回以上クエリされます。これらを行うには1時間以上かかります。
いくつかの組み込み機能を利用してこれらを高速化できますか(または「スマート」な方法で実行できますか)?そして、ETLおよび/またはSSISのコンテキストでは、1時間は長い時間ですか?
Foreach列挙子を使用せずにこれを実現できます。これを実現するには、1つのデータフロータスクを使用するだけです。
まず、データフロータスクを制御フローに追加します
1。 OLEDBソース
DataFlowタスクで、注文テーブルから読み取るOLEDB Source
を追加します(Execute SQL Task
で使用されるのと同じコマンド(質問の最初のステップ)
Select * FROM Order
また、customerテーブルから読み取る2番目のOLEDB Source
を追加します。
select * FROM CRM
2。ソート
各OLEDBソースの後に、ソースコンポーネントを追加します。
CustomerID
列とOrderID
列を選択し、ソートタイプを昇順として選択する必要がありますCustomerID
(sort type = ascending)およびLevelGrantedOn
(sortを選択する必要がありますタイプ=降順)ソート用の列3。マージ結合
マージ結合コンポーネントを追加して、ソートされた両方の出力を結合します。結合キーとして両方の出力からCustomerID
列を選択し、両方のテーブルから必要な出力列を選択します
4。条件付き分割
マージ結合後、条件付き分割を追加して、次の式に一致する行のみをフィルタリングします
[LevelGrantedOn] < [orderdate]
5。スクリプトコンポーネント
使用する必要のある最後のコンポーネントは、各customerIDの最初の行のみを取得するスクリプトコンポーネントです(両方のソースが適切にソートされているため、最初の行を取得するだけでSelect top 1 ... ORDER BY LevelGrantedOn desc
)
スクリプトコンポーネントで、タイプDT_BOOL
の出力列OutFlag
を追加し、次のスクリプトを使用します。
このスクリプトは、customerIDが初めて発生したときにOutFlagをTrueに設定します(TOP 1
と同様)
Public Class ScriptMain
Inherits UserComponent
Dim lstCustomerID As New System.Collections.Generic.List(Of Integer)
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
If lstCustomerID.Contains(Row.ID) Then
Row.OutFlag = False
Else
lstCustomerID.Add(Row.ID)
Row.OutFlag = True
End If
End Sub
End Class
6。条件付き分割
2番目の条件付き分割を追加して上位1行をフィルタリングします。
[OutFlag] == True
7.OLEDB宛先
条件付き分割出力をOLEDB変換先に接続し、列をマップします。
データフロータスクは次のようになります