TSQLまたはC#で行われる日付アライメントとマッチング抽出は最適ですか?
-
16-10-2019 - |
質問
最初から:私のタイトルはひどいので、新しいタイトルを把握するのを手伝ってくれませんか?
ここにすべてのSQLを投稿することはできません(多くの場合、3万文字以上)ので、私はそれを貼り付けました Pastebin.com
問題:
いくつかのレコードをこするXMLファイルを取得し、レコードからいくつかのデータを抽出し、それから別のテーブルを構築する必要があります。レコードは、イベントがオフになって出てくるためのものであり、再作成のためにパステビンにサンプルデータを含めました。データを見ることなく、説明するのは難しいです。サンプルのインポートから持っているすべてのデータを提供しました。これはアプリを構築するのに十分なはずですが、データに表示されているものよりも多くの情報を取得していません。
これが理にかなっているので、データを一目見ます。
だから私がしなければならないのはこれです:「オフ」イベントごとに、私はそれを次の「オン」イベントに一致させる必要があり、最後に2つのテーブル、「歴史的なイベント」と1つのテーブルのテーブルが1つあります「現在のイベント」の場合。ただし、「歴史的な出来事」を正しく構築することができれば、それから「現在の出来事」を取得する方法を理解できます。
ビジネスルール:
「オン」イベントの前に2つ以上の「オフ」イベントが収集された場合、最古の「オフ」イベントを維持します。 「オフ」イベントの前に2つ以上の「オン」イベントが収集された場合、最新のイベントを「イベント」に保ちます。完全なペアがある場合は、歴史的なテーブルに入れてください。 「オフ」イベントがあり、「オン」イベントではなく「オフ」イベントがある場合は、現在のテーブルに入れてください(したがって、このテーブルから挿入/削除を続けたい場合は、それも問題ありません)。現在のテーブルにすでに「オフ」イベントがある場合は、読み取られている「オン」イベントのために履歴テーブルに移動できます(これは後で実装する必要がありますが、ペアリングを一致させることができれば最初は今のところ前進することができます。
ロジックにとってはそれがほとんどそれだと思います。私の考えは、SQLでこれを行う方法を理解することです また C#で記述されたアプリに押し出し、C#の一時的なリストでそれを実行し、使用する必要があるものを構築します...次のロジック。これはC#では無限に簡単かもしれませんが、SQLがC#ができるのと同じくらい簡単にこの仕事をすることができると感じているので、DBAの達人からの助けが必要でした。
私がすでに持っていないクエリは機能していません, 、しかし、それは私が金曜日に家に帰る前に私が始めたところで、それ以来それを熟考し、私がオンラインで投稿できるサンプルの問題を構築しています(そして、あまりにもあまりにもあなたが知っている)。データはライブデータであり、正確です。ただし、IDが匿名化されており、テキストフィールドが単純な作業できるものに変更されています。
これは、データを最後にどのように見てもらいたい方法と今の見方を示すスプレッドシートです。現在のデータ(明確にするために各IDの間にスペーサーの行があります)、履歴テーブルにあるデータ(理解のために元のデータのIDに沿った)、および現在のテーブル(もう一度整列)があります。これがビジネスルールを明確にするのに役立つことを願っています。https://spreadsheets.google.com/ccc?key=0auvcdehuvu5ddhrcnkpuwhbureprajlu5vx2xswnc&hl=en&authkey=coq7y50h
解決 2
したがって、継続的な解説のために、そしておそらく何が答えになるでしょうか:
私はちょうど先に進み、それをC#にエクスポートし、そこで処理しました。セットよりも手続き的に行う方が簡単で、最初、オフ、またはオン(それらが同時にある場合)を把握する必要があります。彼らのPMと協力して知ることができますが、私は彼らがどちらが起こるかわからないと感じています。
とにかく、すべての議論が1つの場所に保持されるように、この成績証明書も参照してください:(あなたが本当に興味があるなら) http://chat.stackexchange.com/rooms/179/conversation/date-alignment-and-matching-extraction-extraction-done-with-tsql-or-c だからそれがあります。
他のヒント
これは、私が横たわっていたいくつかの仕事に基づいて、私がいじっていたものです。それ そうではありません クラスタリングされたイベントを1回適切に処理します。とにかく理論的には役立つ可能性があります... :)
;WITH ordered_rows AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY Identifier ORDER BY EventTime) AS Row,
Identifier, Type, EventTime, DiscoveredDate, FileId FROM #EventDataTemp
)
,filtered_rows AS
(
SELECT Row, Identifier, Type, EventTime, DiscoveredDate, FileId,
CAST(CASE Type WHEN 'Went Off' THEN 1 ELSE NULL END AS INT)
AS OffEventRow
FROM ordered_rows
WHERE Row = 1
UNION ALL
SELECT o.Row, o.Identifier, o.Type, o.EventTime, o.DiscoveredDate, o.FileId,
CAST(CASE WHEN o.Type = 'Went Off' AND f.Type = 'Went Off'
OR o.Type = 'Came On' THEN f.OffEventRow ELSE o.Row END AS INT)
FROM ordered_rows o INNER JOIN filtered_rows f
ON o.Row = f.Row + 1 AND o.Identifier = f.Identifier
)
,on_events AS
(
SELECT Identifier, OffEventRow, MAX(Row) AS OnRow
FROM filtered_rows
WHERE Type = 'Came On' AND OffEventRow IS NOT NULL
GROUP BY OffEventRow, Identifier
)
SELECT f.Identifier, f.Type, f.EventTime, f.DiscoveredDate, f.FileId
FROM filtered_rows f LEFT JOIN on_events o
ON f.Identifier = o.Identifier
AND f.Row = o.OnRow
WHERE f.Type = 'Went Off' AND f.Row = f.OffEventRow
OR f.Type = 'Came On' AND o.OnRow IS NOT NULL
ORDER BY f.Identifier, f.EventTime