如何使用索引(或任何其他方法)追加行?

时间:2019-07-14 00:11:44

标签: database sqlite indexing

我有一个包含6列和450万行的数据集,我想遍历所有数据集以比较数据集中每一行的最后一列的值与第一列的值并将最后一列的值与该行的第一列的值匹配的行附加到该行。第一列和最后一列都已建立索引,但都不是整数。

我在stackoverflow中问了同样的问题,并得到了一个很好的答案,该答案基于numpy和对数据进行排列,但是对于一个相当大的数据集来说,它太慢了。

假设这是我的数据集(在实际数据集中,第一个和最后一个元素不是整数):

x = [['2', 'Jack', '8'],['1', 'Ali', '2'],['4' , 'sgee' , '1'],
['5' , 'gabe' , '2'],['100' , 'Jack' , '6'],
['7' , 'Ali' , '2'],['8' , 'nobody' , '20'],['9' , 'Al', '10']] 

结果应如下所示:

[['2', 'Jack', '8', '1', 'Ali', '2', '5' , 'gabe' , '2','7' , 'Ali' , '2'],
 ['1', 'Ali', '2', '4' , 'sgee' , '1'],
['8' , 'nobody' , '20', '2', 'Jack', '8']]

我认为我可以使用索引来使过程更快,但是我对数据库的了解非常有限。有没有人有解决方案(使用索引或任何其他工具)?

该问题的numpy解决方案如下: How to compare two columns from the same data set?

以下是指向sqlite中的真实数据示例的链接:https://drive.google.com/open?id=11w-o4twH-hyRaX8KKvFLL6dQtkTKCJky

1 个答案:

答案 0 :(得分:1)

基于SQL的潜在解决方案可能如下(我使用的是大样本数据库作为参考):

为使建议的解决方案高效,我将执行以下操作:

在最后一列上创建索引,并创建部分索引以消除第一列和最后一列相同的行。这是可选的,因此如果您认为这会导致问题,可以从以后的查询中删除它。但是,如果您这样做,则应在第0列上创建一个完整索引。为了完整起见,此处都包括了这三个索引。

CREATE INDEX [index_my_tab_A] ON [tab]([0]);
CREATE INDEX [index_my_tab_B] ON [tab]([5]);
CREATE INDEX [index_my_tab_AB] ON [tab]([0]) where [0] != [5];
ANALYZE;

然后,我将利用联接行为来生成所需的列表,以产生所需的结果。通过将表自身连接起来,可以为所考虑的每一行获得多个返回行。

SELECT * from tab t1
JOIN tab t2 on t2.[5] = t1.[0] 
WHERE t1.[0] != t1.[5]
AND t2.[5] != 'N/A' -- Optional
ORDER by t1.[0];

在您的大型示例数据库上运行SQL(在ANALYZE步骤完成之后)在我的计算机上花费了0.2秒。它产生了三行匹配,我认为这是正确的。 结果表的含义可能不太明显,因此这是上面的查询针对原始帖子中提供的小样本运行时给出的结果。 (对SQL进行了稍微的修改,以处理减少的列数)……运行时,它产生以下结果,该结果与您最初想要的结果相同:

1  Ali      2   4   sgee   1
2  Jack     8   1   Ali    2
2  Jack     8   5   gabe   2
2  Jack     8   7   Ali    2
8  Nobody  20   2   Jack   8

您要做的就是遍历此结果列表,并将行合并以生成您指定的列表。此处的总体思路是将第二个条目三项添加到第一个条目三项中,直到第一个条目三项发生变化,但只包含第一个条目三项。

因此,从第一行开始,您将把Ali三人组合和sgee三人组合起来,为您提供['1','Ali','2','4','sgee','1']

然后,您将合并三个杰克行,从而得到['2','Jack','8','1','Ali','2','5','gabe','2', '7','Ali','2']

然后最后一行合并为['8','nobody','20','2','Jack','8']

这与您指定的三个数组匹配(尽管顺序不同)

注意:您的原始问题并未指出在同一行中第一列和最后一列匹配的情况下您期望得到什么结果... [3,George,3]因此... where子句消除了两种条目。我在您的大样本数据中注意到,当col 0和col 5相同时,会有很多行。因此,where子句从考虑中消除了这些行。我注意到的第二件事是,第5列中有许多行都具有“ N / A”,因此我也将其从考虑中删除了。