确定每周数据系列中交易的算法?


9

我正在尝试开发一个小型报告工具(具有sqlite后端)。我可以最好地将此工具描述为“交易”分类帐。我正在尝试做的是跟踪每周数据提取中的“交易”:

  • “新”(或添加)-资源对于我的应用程序来说是新的,因为我的应用程序之前可能没有跟踪过该资源,因为尚未通过提取看到它。
  • “更新”(或命中)-最近使用了该资源,将保留期再更新一周。
  • “删除”(或删除)-自上次报告以来该项目未使用(可选,但是可以很好地绘制出每周对资源需求的变化图)。

我所得到的只是每周的数据提取(以竖线分隔的平面文件),这些数据来自我无法控制的旧版归档/记录管理系统。

每一行都可以大致提炼为:
resource_id | resource info | customer_id | customer_info

样本数据:

10| Title X       | 1 | Bob
11| Another title | 1 | Bob
10| Title X       | 2 | Alice

目的是使报告X个月未使用过的资源变得容易(基于最后一次点击)。在保留期中,如果资源很受欢迎,则将其保留在附近以便于访问。尚未使用18个月的资源已标记为可在其他地方进行长期存档。

这一定是一个普遍的问题。想知道是否有通用算法来确定数据集之间的新内容/相同内容/已删除的内容(数据库还是最新摘录)?

Answers:


1

好吧,您的答案是...是的。您可以实现一个简单的算法,不需要任何其他东西。这是一个净现值算法。它很容易实现,并且在数据库端所需要的只是对每周数据添加日期戳并编写一个简单的查询和一个小的递归函数或for循环,或者您可以执行其他解决方案之一。

NPV = PV-(PV(CP / T)或新现值等于现值乘以当前期间(自上次输入以来的月数)除以期限(例如18个月),当资源值降至0时即为净现值被消耗。

如果您给我一个lang,请输入我的代码,然后在编辑中


语言不是那么重要。如果我必须选择Ruby或C ++。如果您可以使用HTML 4.0 Strict编写算法,那么您将成为我的英雄。开玩笑的最后一部分:)
Swartz

会对代码感兴趣。Ruby或C ++。谢谢。
Swartz

0

如果您仍将更新保存在SQLite后端中,则可以在合并之前将每周更新变成一个新表,并将其与带有查询的已存档数据进行比较。

使用SQL查找表的新添加项的示例:https : //stackoverflow.com/questions/2077807/sql-query-to-return-differences-between-two-tables

如果您数据库中的一个字段存储了交易日期,则可以查询过去18个月中进行过交易的所有用户。然后,存档只是完整的数据库。或者,您可以查询所有还没有的用户,提取其数据,然后删除它们。更新仅是本周加上时间戳的任何行。


更好的是,至少这是一个以数据为中心的解决方案,但这仍然是过大的杀伤力
J-Boss

我正在使用sqlite,因为它很容易开始。可以轻松切换到MySQL(或PostgreSQL)。如果使用no-SQL后端可以使一切变得更好,我很高兴。
斯沃茨

好了,我的想法是,主要是你在一个数据库将其转换为行。如果您不需要从多个进程中同时运行它,我认为您不想切换到比SQLite更强大的功能。
戴维斯洛

无需并发处理。但是我需要将有关资源的数据存储在某个地方。SQL db似乎是一个不错的选择,但是,没有什么阻止我将数据加载到任何数据类型中以处理增量的。在每次提取运行结束时,我想要的是找出新内容,保持不变的内容和消失的内容。我可以从此信息中找出如何根据需要更新记录。
斯沃茨

解析数据并将其放入数据库后,写查询可能比实现算法更简单。就是说,如果您确实想对它进行编码,则所需的算法会有所不同,并且在将C ++ STL中的两个数据集都放入容器后,就可以在一行中使用它来实现它。您的选择,可能是一个Vector
戴维斯洛

0

替代方案:

  1. 将事务列表解析为某种数据结构,例如数组。(在C ++中,请思考Vector,在Java中,请参见ArrayList。)

  2. 在您的SQL后端上执行查询,例如,SELECT DISTINCT customer_id FROM Transactions ORDER BY customer_id然后将排序后的不同客户ID打包到一个集合中old。如果使用WHERE分隔新旧事务的子句进行完全相同的操作,则可以跳过步骤3。

  3. 将新更新中的唯一客户ID按排序顺序放入单独的数据结构中。您可以使用几种数据结构来获取数据结构new。将排序插入到双向链接列表中非常简单,但是使用中间哈希表将在接近线性时间的情况下运行,或者如果您仍在对原始数组进行排序,则很容易获得一个集合。

  4. 与众不同new- old使用您喜欢的语言的标准库。您最喜欢的语言的标准库中是否包含此算法?

您要做的其他事情肯定是更新事务数据库后的SQL查询。

请注意步骤3:考虑数据的性质。假设您的文本文件按时间顺序列出了订单,并且在通常的一周内,有许多新客户customer_id按升序获得新订单。假设大多数其他订单来自少数忠实的回头客,而订单量较低customer_id。然后,您的输入已经大部分排序了。在这种情况下,您尝试customer_id在双向链接列表的前面插入低端而在后面插入高端的插入排序方式customer_id在实践中会表现良好。


1
我对新/相同/更新的资源而不是客户更感兴趣。但是,是的,想法是一样的。
斯沃茨

0

据我从您的问题中了解到,您实际上有resource_id(+ info)和客户的“列表”(id + info)。

因此,您可以轻松保留每个资源的客户列表,并检查资源上每个列表的最后一个节点(以便了解上次操作时间;您只需要在代码中为您的客户添加日期字段)

我对SQL不熟悉,因此我用HashMap和List 给出了示例,但我确定它是相同的想法:HashMap <Resource, List<Customer>>,何时Resource应包含resourceID作为键并Customer应包含客户ID,信息和操作日期。

有了这个想法,您就可以轻松知道上次的操作时间,并且可以修改任何资源(添加\删除资源\客户)。


0

如果您使用的是SqLite数据库,并且还将批次的日期也添加到表格的列中,

10| Title X       | 1 | Bob    | 2015-03-01
11| Another title | 1 | Bob    | 2015-03-01
...............................
10| Title X       | 1 | Alice  | 2015-03-05

使用SQL获取最近X天未使用的资源将非常容易

Select distinct r.ResourceID from Resources r
where not exists (SELECT julianday('now') - julianday(r.DateUpdated)) < X

我没有测试过SQL,但是应该可以给您一个思路


0

在原始帖子中,听起来好像正在提取的数据没有指示交易日期/时间的字段,并且我认为文件是按每天,每小时等时间表定期提取的。

我可以通过添加一个SQL timestamp列来解决此问题,该列可以在数据库级别自动生成,也可以通过提取数据并将其插入到DB中的代码来生成。然后,在该时间戳列上放置一个索引并完成该操作。让DB引擎执行有效的工作,以回答“自该时间以来未发生多少事务”或“此时间与该时间之间有多少事务”这一问题。

然后,您计划一个作业以查询并计算要报告的差异。“新”事务是在您要求“新以来”日期之前数据库中没有任何记录的事务。旧记录是自截止日期以来没有任何交易的记录。


-2

这不是HashTables的目的吗?如果您要做的只是保留过去几个月中已使用过的资源的记录,并删除过去18个月中未访问过的资源,则可以使用HashTable,其中的Key是resource_id,其值是最后访问日期。

要归档18个月以上的记录,您可以遍历哈希表中的所有记录,然后删除(或移动)这些特定记录。(您可以在报告进入时每周执行一次此操作)


如果我在数据库中存储内容,为什么需要HashTable?我可以对数据库记录进行更新。我对一种情况更感兴趣:获取两个数据集,找出两个数据集之间的差异(添加的内容,保持不变的内容,删除的内容)。HashTable技术将如何帮助查找新记录和“已删除”记录?
斯沃茨

如果表在数据库中建立了索引,那么它们基本上也是后台的HashTables。如果您有2个表,每个表代表一个数据集,则可以通过执行一些外部联接来获取新记录和已删除记录。请参阅以下内容以供参考:i.stack.imgur.com/pxUO3.png。确保在resource_id列上有索引,并且应该很快。如果必须从头开始实现这一点,那么我认为HashTables仍然是您可以使用的方法,因为您可以在O(1)摊销时间内进行查找/插入/删除。想不到一种更有效的方法来做到这一点。
Adrian Buzea 2015年

3
有更好的数据结构可以处理老化,而无需执行将其塞入哈希表的额外步骤。

介意提些?
Adrian Buzea 2015年

@Snowman-我希望我能再评价几遍,我只想对此评论表示赞同
J-Boss
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.