最好使用 TSQL 或 C# 完成日期对齐和配对匹配提取吗?

jco*_*and 6 sql-server-2008 query

首先:我的头衔很烂,所以帮我找出一个新的?

我不能在这里发布所有的 SQL(超过 30k 个字符),所以我把它贴在了pastebin.com

问题:

我得到一个 XML 文件,我从中抓取了一些记录,我需要从记录中提取一些数据并建立另一个表。这些记录是关于一个事件的发生和发生,我已经在 pastebin 中包含了示例数据以进行重新创建。没有看到数据,很难解释。我已经提供了从我的示例导入中获得的所有数据,这些数据应该足以构建应用程序,但我没有得到比数据中显示的更多的信息。

我会给你一点时间看一眼数据,所以这是有道理的。

所以我需要做的是:对于每个“关闭”事件,我需要将它与下一个“开启”事件相匹配,最后我需要有两张桌子,一张桌子用于“历史事件”,一张桌子为“时事”。但是,如果我能正确构建“历史事件”,我就可以弄清楚如何从中获取“当前事件”。

商业规则:

如果在“on”事件之前收集了两个或更多“off”事件,请保留最旧的“off”事件。如果在“关闭”事件之前收集了两个或更多“开启”事件,则保留最新的“开启”事件。如果有一个完整的对,把它们放在历史表中。如果有一个“关闭”事件而不是一个“开启”事件,把它放在当前表中(所以如果我想继续从这个表中插入/删除,那也很好)。如果当前表中已经存在“关闭”事件,我可以将其移动到历史表中以读取“开启”事件(这将需要稍后实施,但如果我可以匹配配对最初我现在可以继续前进。

我认为这就是逻辑。我的想法是弄清楚如何在 SQL 中执行此操作,或者将其推送到用 C# 编写的应用程序,并使用 C# 中的一些临时列表来执行此操作,并构建我需要用于...下一个逻辑的内容。这在 C# 中可能要容易得多,但我感觉 SQL 可以像 C# 一样轻松地完成这项工作,所以我需要 dba 大师的一些帮助。

我的查询已经不起作用,但这就是我在周五回家之前开始的地方,从那时起我一直在考虑它,并构建一个我可以在网上发布的示例问题(以及整个生活你也知道)。数据是实时数据且准确无误,除了 ID 被匿名化并且文本字段更改为易于使用的内容。

这是一个电子表格,大致显示了我希望数据在最后的样子以及现在的样子。有当前数据(为了清晰起见,每个ID之间有一个间隔行),历史表中的数据(与原始数据的ID对齐以便理解)和当前表(再次对齐)。我希望这可以帮助澄清业务规则。 https://spreadsheets.google.com/ccc?key=0AuvCdeHuVU5ddHRCNkpuWHBUREpRajlmLU5VX2xsWnc&hl=en&authkey=COq7y50H

所以完整的 SQL 包括 tabledefs 和当前(非常不正确的)查询在 pastebin http://pastebin.com/k2f2CLnQ

moo*_*tor 6

这是我根据我的一些工作摆弄的东西。它不能很好地处理一次聚集的事件。无论如何,理论上它可能会有所帮助...:)

;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
Run Code Online (Sandbox Code Playgroud)


jco*_*and 2

因此,对于继续评论,以及可能的答案:

我刚刚将其导出到 C# 并在那里进行处理。按程序进行比按集合更容易,而且我仍然需要弄清楚哪个先出现,关闭或打开(当它们并发时)。与他们的 PM 合作才知道,但我有一种感觉,即使他们也不知道什么时候发生。

无论如何,为了让所有讨论都保存在一个地方,也请参阅此文字记录:(如果您真的感兴趣)http://chat.stackexchange.com/rooms/179/conversation/date-alignment-and-pair-匹配提取最佳完成与 tsql-or-c就是这样。