将基于另一个的不同总和和计数列添加到 VB.NET 中的数据表
Adding distinct sum and count columns based on another to datatable in VB.NET
我有一个超大数据表(来自我的 PostgreSQL 数据库中的分隔字符串单元格),行数约为 40k。示例数据列:
invoice customer_id amount
1 1 150,50
2 1 149,50
3 2 50,50
4 3 49,50
我正在尝试向此 DataTable 添加 2 列。一个应该显示发票数量(customer_id 计数),而另一个应该显示每个客户的金额总和,如下所示:
invoice customer_id amount invoice_count amount_total
1 1 150,50 2 300,00
2 1 149,50 2 300,00
3 2 50,50 1 50,50
4 3 49,50 1 49,50
使用这个:
For i = 0 To dt.Rows.Count - 1
Dim distinctDT As DataTable = dt.DefaultView.ToTable(True, "customer_id", "amount")
distinctDT.DefaultView.RowFilter = "customer_id = " & dt.Rows(i).Item("customer_id")
dt.Rows(i).Item("count") = distinctDT.DefaultView.Count
Next
有效,但需要很长时间(整个 DataTable 大约需要 2 小时!),因为每个 'i' 都会创建辅助数据表(我认为是这样)。在 Postgres 中,我可以简单地在 Select 中使用 count(customer_id) over(partition by customer_id)
并按 customer_id
分组,我的查询结果会在几秒钟内显示出来。
是否可以在不创建不同的数据表并在每个 'i' 滴答时过滤它的情况下解决这个问题?提前致谢!
您可以使用 LINQ 的强大功能,在本例中结合类似于字典的 Lookup(Of TKeyx, TValue)
。效率高,代码简洁易读:
Dim customerLookup = dt.AsEnumerable().ToLookup(Function(r) r("customer_id"))
For Each row As DataRow In dt.Rows
Dim customerRows = customerLookup(row("customer_id"))
row("count") = customerRows.Count()
row("amount_total") = customerRows.Sum(Function(r)row.Field(Of Decimal)("amount"))
Next
我有一个超大数据表(来自我的 PostgreSQL 数据库中的分隔字符串单元格),行数约为 40k。示例数据列:
invoice customer_id amount
1 1 150,50
2 1 149,50
3 2 50,50
4 3 49,50
我正在尝试向此 DataTable 添加 2 列。一个应该显示发票数量(customer_id 计数),而另一个应该显示每个客户的金额总和,如下所示:
invoice customer_id amount invoice_count amount_total
1 1 150,50 2 300,00
2 1 149,50 2 300,00
3 2 50,50 1 50,50
4 3 49,50 1 49,50
使用这个:
For i = 0 To dt.Rows.Count - 1
Dim distinctDT As DataTable = dt.DefaultView.ToTable(True, "customer_id", "amount")
distinctDT.DefaultView.RowFilter = "customer_id = " & dt.Rows(i).Item("customer_id")
dt.Rows(i).Item("count") = distinctDT.DefaultView.Count
Next
有效,但需要很长时间(整个 DataTable 大约需要 2 小时!),因为每个 'i' 都会创建辅助数据表(我认为是这样)。在 Postgres 中,我可以简单地在 Select 中使用 count(customer_id) over(partition by customer_id)
并按 customer_id
分组,我的查询结果会在几秒钟内显示出来。
是否可以在不创建不同的数据表并在每个 'i' 滴答时过滤它的情况下解决这个问题?提前致谢!
您可以使用 LINQ 的强大功能,在本例中结合类似于字典的 Lookup(Of TKeyx, TValue)
。效率高,代码简洁易读:
Dim customerLookup = dt.AsEnumerable().ToLookup(Function(r) r("customer_id"))
For Each row As DataRow In dt.Rows
Dim customerRows = customerLookup(row("customer_id"))
row("count") = customerRows.Count()
row("amount_total") = customerRows.Sum(Function(r)row.Field(Of Decimal)("amount"))
Next