Pivot Table 實現詳解(一)

來源:互聯網
上載者:User

Pivot Table 是樞紐分析表的意思,如下一個普通的資料集:

當按日期作為x軸,客戶ID作為y軸,利潤作為資料(SUM),轉換為樞紐分析表後呈現為:

其中的利潤資料將被合計,而無資料的位置被“-”字元代替。

 

那麼實現一個這樣的資料展現模式,方法有多種,在排開專用工具軟體之外,一般存在三種方式:

一、使用支援多維展示資料的網格控制項或報表控制項。

二、編寫SQL來實現。

三、通過編程開發自訂的函數將資料做轉換。

 

這三種方式,它們各有優缺點:

一、使用網格控制項則必須購買三方廠商開發的組件,而報表工具/組件則只能在特定的情境應用並展示資料。

二、SQL方式只是相對靈活,但如果x軸是動態,如年月日,或者是某個項目(沒有參照表),就需要代碼來拼接SQL,不能寫死,但這種方式的功能卻很強大,像彙總函式之類的,通常在報表中,就是先寫SQL儘可能的接近於最終格式,再使用報表工具最佳化或處理資料格式。

三、編程方式,優點是可以很靈活的公開介面和實現需求,缺點是如果要做的完善,工作強度相對比較大(技術基礎,開發時間,可用性,穩定性,效能)。

 

通常要滿足一、二兩點,是相對容易的,而第三點編程方式相對來說,可利用的資源不多;因為最合適的還是自己根據項目需求而定製開發的。

 

那麼針對第三點編程方式的思路做以下講解:

一、樞紐分析表的x軸和y軸的

這裡的x軸和y軸表示為

x軸的列提取:

構造新記憶體表;
排除X軸欄位和資料欄位,將其他欄位產生Y軸列;
foreach (資料列 列 in 原始表.列集合)
if (列名稱!=X軸欄位 && 列名稱!=資料欄位)
    新記憶體表.增加列(列);
從資料中找出欄欄位值產生列;
foreach (資料行 行 in 原始表.行集合)
if (行[X軸欄位]不存在)
    新記憶體表.增加列(行[X軸欄位]);

y軸的資料分組過濾和資料列填入:

 

//遍曆資料,填寫資料
foreach (資料行 行 in 原始表.行集合)
{
    //比較分組列資料,保持唯一
    string 比較值一 = 行[Y軸欄位];
    bool 存在相同 = 新記憶體表.行集合.尋找(比較值一);
    //無相同的,則增加到分組資料集合
    if (!存在相同)
    {
        構造記憶體表新行;
        //複製分組列資料
        新行[Y軸列] = 行[Y軸列] ;
    }
    //尋找資料列的資料
    foreach (資料行 尋找行 in 新記憶體表.行集合)
    {
        string 比較值二 = 尋找行[Y軸欄位];
        //如果和分組資料相同,則增加到對應的資料儲存格
        if (比較值一==比較值二)
            尋找行[行[X軸列] + ""] = 行[資料列];
    }
}

二、資料列的彙總實現

彙總函式運算,思路是在填寫x軸的資料欄位資料的時候,將它的原始值登記到一個運算表內,作為儲存;其中y軸資料作為key,x軸資料作為它子集的key,再在其中存放一個有序的List,其中存放的則是每行的未經處理資料值。

//彙總函式運算表
Dictionary<y軸列行資料, Dictionary<x軸列, List<x軸列資料集合>>> expressRows;

此圖比較大,請配合下面的偽碼

//拿到了集合,後計算彙總函式和填充空文本
foreach (資料行 尋找行 in 新記憶體表.行集合)
{
    string 比較值二 =尋找行[Y軸欄位];
    //尋找需要計算的儲存格
    foreach (string x軸列 in x軸列集合)
    {
        decimal avg, sum, max, min;
        avg = sum = max = min = 0;
        //排除空
        if (彙總函式運算表.ContainsKey(比較值二) && 彙總函式運算表[比較值二].ContainsKey(x軸列))
        {
        //產生彙總結果
        foreach (decimal d in 彙總函式運算表[比較值二][x軸列])
        {
            avg += d;
            sum += d;
            if (d > max) max = d;
            if (min == 0) min = d;
            if (min > d) min = d;
        }
        //平均特殊處理
        if (彙總函式運算表[比較值二][x軸列].Count > 0)
            avg = avg / 彙總函式運算表[比較值二][x軸列].Count;
        else
            avg = 0;
        //分配彙總結果
        if (dataExpression != PivotDataExpression.None)
        {
            switch (dataExpression)
            {
            case PivotDataExpression.Avg:
                尋找行[x軸列] = avg;
                break;
            case PivotDataExpression.Max:
                尋找行[x軸列]= max;
                break;
            case PivotDataExpression.Sum:
                尋找行[x軸列]= sum;
                break;
            case PivotDataExpression.Min:
                尋找行[x軸列]= min;
                break;
            case PivotDataExpression.Count:
                尋找行[x軸列]= 彙總函式運算表[比較值二][x軸列].Count;
                break;
            }
        }
        }

        //填充空文本
        if (尋找行.IsNull(x軸列))
        尋找行[x軸列]= 空文本;
    }
}

三、x軸和y軸的合計或公式套用的靈活實現

待續……

四、x軸和y軸的合計列實現

待續……

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.