将基于另一个的不同总和和计数列添加到 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