注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

樱之花

叶散的时候,你明白欢聚;花谢的时候,你明白青春.

 
 
 

日志

 
 
关于我

分类中“我的实验室”是我在日常工作中的一些知识总结,有些写的比较匆忙,可能大家在阅读时会产生困扰,后期有时间我会重新整理编辑,谢谢大家的到访,您们的支持是我前进的动力!

网易考拉推荐

027 关于数据分组排名的算法  

2012-11-26 17:48:36|  分类: 我的实验室 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

最近接到一个任务,是对数据表查询出的一组数据进行排名,要求按不同的分组计算。我大概想了一下,如果直接操作datatable是可以实现的,当然还有其他方法,但是之所以首先想到datatable操作,是因为所写的程序中很多都是用datatable去做的,为了写法的统一性首先就想到了这个方法。为了实现这个需求,我首先做了一个简单的例子,并且用了少量的数据,来测试了我的想法。最终结果还是可行的,我先把刚做出来的例子简单做个描述吧。
这是怎么样的一个排名呢,举例子来讲,查询结果里有大区、省办、城市、客户编号、销量,现在要求按销量来分别统计客户所属城市、省办、大区和全国的排名情况。

1.假如把这个数据表查询结果定义为表名tbl,如果要求排名,可以分别对数据表tbl按分组(大区、省办、城市、客户)和销量从高到低排序,再把每一种分组结果按客户编号关联起来。

1)定义每一种分组的查询结果为,按大区tbl1,按省办tbl2,按城市tbl3,按客户(即按全国)tbl4,

2)使用左联接,按客户编号关联,伪代码如下:

tbl left join tbl1 on tbl.custid=tbl1.custid

tbl left join tbl2 on tbl.custid=tbl2.custid

tbl left join tbl3 on tbl.custid=tbl3.custid

tbl left join tbl4 on tbl.custid=tbl4.custid

2.用datatable实现以上步骤。主要使用了datatable的Select()方法和dataset的Relations属性

3.另外我还定义了一个排名算法,当按分组排序时,要判断是否在同一分组,比如,当按城市排序时,只能在同一个城市里做比较,不能跨城市;当按省办排序时,只能在同一个省办里做比较,不能跨省办。另外,主要要考虑销量相等时,排名的所在位置是相同的。

stype表示按什么排名,如是按大区、省办、城市。snum表示所要排名的依据,比如销量。注意,当stype为空时,表示按全国排名。

     Private Function CmpPm(ByVal stype As String, ByVal snum As String) As DataTable
        Dim i As Integer = 0
        Dim demostr As String = ""
        Dim dt_saofpm As New DataTable
        dt_saofpm = InitDtGj()

        Dim drs2() As DataRow
        If stype = "" Then
            drs2 = dt.Select("", snum & " desc")
        Else
            drs2 = dt.Select("", stype & "," & snum & " desc")

            If dt.Rows.Count > 0 Then
                demostr = drs2(0).Item(stype)
            End If
        End If

        Dim total As Integer = dt.Rows.Count
        Dim index As Integer

        For Each thedr As DataRow In drs2
            dt_saofpm.Rows.Add()
            dt_saofpm.Rows(dt_saofpm.Rows.Count - 1).Item("custid") = thedr("custid")
            dt_saofpm.Rows(dt_saofpm.Rows.Count - 1).Item("gjpm") = i + 1

            If stype = "" Then
                If index < total - 1 Then
                    If drs2(index).Item(snum) <> drs2(index + 1).Item(snum) Then
                        i = i + 1
                    End If
                End If
            Else
                If index < total - 1 Then
                    If demostr <> drs2(index + 1).Item(stype) Then
                        demostr = drs2(index + 1).Item(stype)
                        i = 0
                    ElseIf drs2(index).Item(snum) <> drs2(index + 1).Item(snum) Then
                        i = i + 1
                    End If
                End If
            End If
          
            index = index + 1
        Next
        Return dt_saofpm
    End Function

 

    Private Function InitDtGj() As DataTable
        Dim dts As New DataTable
        dts.Columns.Add("custid", System.Type.GetType("System.String"))
        dts.Columns.Add("gjpm", System.Type.GetType("System.Decimal"))

        Return dts
    End Function

4.最终实现:
排名方式:大区:daqupm,省办:provpm,城市:saofpm,全国排名:qgpm
dtend表示最终关联组成的结果
       Dim ds As New DataSet
        ds.Tables.Add(dt)
        Dim dt4 As New DataTable
        dt4 = CmpPm("", "num")
        Dim dt1 As New DataTable
        dt1 = CmpPm("daqu", "num")
        Dim dt2 As New DataTable
        dt2 = CmpPm("prov", "num")
        Dim dt3 As New DataTable
        dt3 = CmpPm("saof", "num")
        ds.Tables.Add(dt1)
        ds.Tables.Add(dt2)
        ds.Tables.Add(dt3)
        ds.Tables.Add(dt4)
        ds.Relations.Add("左联", dt.Columns("custid"), dt1.Columns("custid"), False)
        ds.Relations.Add("左联2", dt.Columns("custid"), dt2.Columns("custid"), False)
        ds.Relations.Add("左联3", dt.Columns("custid"), dt3.Columns("custid"), False)
        ds.Relations.Add("左联4", dt.Columns("custid"), dt4.Columns("custid"), False)

        Dim dtend As New DataTable
        dtend = dt.Clone
        dtend.Columns.Add("daqupm", System.Type.GetType("System.Decimal"))
        dtend.Columns.Add("provpm", System.Type.GetType("System.Decimal"))
        dtend.Columns.Add("saofpm", System.Type.GetType("System.Decimal"))
        dtend.Columns.Add("qgpm", System.Type.GetType("System.Decimal"))

        Dim parentRow As DataRow
        For Each parentRow In ds.Relations("左联").ParentTable.Rows
            dtend.ImportRow(parentRow)
            For Each childRow As DataRow In parentRow.GetChildRows(ds.Relations("左联"))
                dtend.Rows(dtend.Rows.Count - 1).Item("daqupm") = childRow("gjpm")
            Next
            For Each childRow As DataRow In parentRow.GetChildRows(ds.Relations("左联2"))
                dtend.Rows(dtend.Rows.Count - 1).Item("provpm") = childRow("gjpm")
            Next
            For Each childRow As DataRow In parentRow.GetChildRows(ds.Relations("左联3"))
                dtend.Rows(dtend.Rows.Count - 1).Item("saofpm") = childRow("gjpm")
            Next
            For Each childRow As DataRow In parentRow.GetChildRows(ds.Relations("左联4"))
                dtend.Rows(dtend.Rows.Count - 1).Item("qgpm") = childRow("gjpm")
            Next
        Next
        Me.DataGridView1.DataSource = dtend
 
  评论这张
 
阅读(731)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017