-- 作者:狐狸爸爸
-- 发布时间:2015/10/25 16:50:00
--
高效随机抽取记录
随机抽取少量记录 如果要从数据表中随机抽取一定数量的记录,例如从员工表随机抽取5个员工,可以参考下面的代码: Dim ids As String Dim lst As new List(of String) Dim cnt As Integer = DataTables("员工").DataRows.Count Do Dim Id As Integer = rand.Next(0,cnt) id = DataTables("员工").DataRows(id)("_Identify") If lst.Contains(id) =False Then lst.Add(id) End If ids = ids & id & "," Loop While lst.count < 5 \'5是要抽取的行数 Tables("员工").Filter = "[_Identify] In (" & ids.Trim(",") & ")" 上面的代码适合随机抽取少量的记录。
随机抽取大量记录 如果随机抽取的记录较多,可以考虑增加一个逻辑列,假定逻辑列的名称为“选择”,可以参考下面的代码: Dim cnt As Integer = DataTables("订单").DataRows.Count Dim nds As Integer = 100 \'要抽取的记录数 Tables("订单").StopRedraw() DataTables("订单").ReplaceFor("选择",False) Do Dim idx As Integer = rand.Next(0,cnt) Dim dr As DataRow = DataTables("订单").DataRows(idx) If dr("选择") = False Then dr("选择") = True nds = nds - 1 End If Loop While nds > 0 Tables("订单").Filter = "[选择] = True" Tables("订单").ResumeRedraw()
上面的代码从订单表中随机抽取100个订单。 建议逻辑列“选择”采用表达式列,不要给其设置表达式即可,因为:没有设置表达式的表达式列,可以通过代码设置此列的值。
用洗牌法抽取记录
上面的代码在抽取的记录数接近于总的记录数时,性能会下降,虽然可以用逆排除的方法提高性能,但是毕竟要多写一半的代码。 我们可以换个思路,用类似洗牌的方法,将记录顺序打乱后再来抽取,性能会相对比较稳定: Dim cnt As Integer = DataTables("订单").DataRows.Count Dim ids1 As New List(of Integer) \'用于存储洗牌前的位置 Dim ids2 As New List(of Integer) \'用于存储洗牌后的位置 For i As Integer = 0 To cnt -1 \'准备初始的牌 ids1.add(i) Next For i As Integer = 0 To cnt - 1 \'开始洗牌 ids2.Add(ids1(rand.Next(0,ids1.count))) Next Tables("订单").StopRedraw() DataTables("订单").ReplaceFor("选择",False) For i As Integer = 0 To 100 - 1 \'100为要抽取的行数 DataTables("订单").DataRows(ids2(i))("选择") = True Next Tables("订单").Filter = "[选择] = True" Tables("订单").ResumeRedraw()
|