使用pivot的pivot输入

ifmq2ha2  于 2021-06-03  发布在  Hadoop
关注(0)|答案(1)|浏览(387)

我需要你的帮助在下面的情况下(使用Pig拉丁语)。
我有以下格式的输入数据:

DATE,ERROR,COUNT
20110212,ORA-00600,9
20110212,ORA-03135,1
20110226,ORA-20000,1
20110305,ORA-03135,1
20110319,ORA-01555,1
20110319,ORA-03135,18
20110326,ORA-00600,1
20110409,ORA-00600,1
20110416,ORA-20000,1
20110423,ORA-01555,2
20110507,ORA-00600,1
20110507,ORA-01555,2
20110514,ORA-00600,1
20110514,ORA-03135,4

我正在寻找如下输出。

DATE,ORA-00600,ORA-03135,ORA-20000....
20110212,9,1,0....
20110514,1,4,0...
20110416,0,0,1...

基本上,我是在关注输入数据;我不能使用嵌套的foreach(带过滤器),因为错误代码(比如ora-00600,ora-03135…)不是常量,而是动态的。
请建议。

8wigbo56

8wigbo561#

关于sql中的pivot功能,我并不感到惊讶。我也有一些项目,我需要一个数据透视结果的使用。电子表格是一个很好的例子(也是企业it界的一个巨大需求)。
数据透视表很好,但是如果您像我一样在动态的制造环境中工作,它们通常会变得很麻烦和复杂。在这种领域,需求总是主观的。会让程序员从根上拔出头发。
正是因为这个原因,我决定在datatable对象上创建一个扩展,它生成一个pivot表,我发现它既快速又有用。
是的,我知道sql的版本,并且仍然知道有一些方法可以使sql中的pivot更加动态(用于更改列)。但我已经学会了保持简单。简单带来了稳定性、可用性、可扩展性和可伸缩性。。这些都是现实企业界的巨大优势。
我现在和你分享这个,希望你能修改它来满足你的需要。它是动态的,而且非常快。。最简单的是。

/// <summary>
/// Creates a PIVOT table based on values in existing table
/// </summary>
/// <param name="PKey">Field used as PIVOT tables Primary (row) Key.</param>
/// <param name="FKey">Field used to create unique column names in PIVOT table.</param>
/// <param name="VKey">Field used as the value for each associated column in a PIVOT table record.</param>
/// <returns>DataTable</returns>
public static DataTable Pivot(this DataTable tbl, string PKey, string FKey, string VKey)
    {
        DataTable retVal = null;
        DataTable keyTbl = null;
        DataTable fldTbl = null;
        DataColumn dc = null;
        DataRow newRow = null;

        Type pkType = null;
        Type valType = null;

        string strPkeyFilter = null;
        string prevFilter = null;

        try
        {
            // Get previous filter (save)
            prevFilter = tbl.DefaultView.RowFilter;

            if (tbl.Rows.Count > 0)
            {
                // Get unique Primary Keys and Field Names
                keyTbl = tbl.DefaultView.ToTable(true, PKey);
                fldTbl = tbl.DefaultView.ToTable(true, FKey);

                if (fldTbl.Rows.Count > 0)
                {
                    // Get Primary Key data type and create column on Pivot table.
                    pkType = tbl.Columns[PKey].DataType;
                    retVal = new DataTable(tbl.TableName);
                    retVal.Columns.Add(new DataColumn(PKey, pkType));
                    retVal.PrimaryKey = new DataColumn[] { retVal.Columns[PKey] };

                    // Get VALUE columns data type
                    valType = tbl.Columns[VKey].DataType;

                    // Create Primary Key filter
                    strPkeyFilter = "{0} = {1}";
                    if(pkType.Equals(typeof(string)))
                        strPkeyFilter = "{0} = '{1}'";

                    foreach (DataRow dr in fldTbl.Rows)
                    {
                        // Create additional rows in Pivot table based on unique Field Names
                        dc = new DataColumn(Convert.ToString(dr[FKey]), valType);
                        dc.AllowDBNull = true;
                        dc.DefaultValue = DBNull.Value;
                        retVal.Columns.Add(dc);
                    }

                    // Iterate through Primary Key collection
                    foreach (DataRow dr in keyTbl.Rows)
                    {
                        // Set Primary Key row filter on base table
                        tbl.DefaultView.RowFilter = string.Format(strPkeyFilter, PKey, dr[PKey]);
                        if (tbl.DefaultView.Count > 0)
                        {
                            // Create new row on Pivot table and set Primary Key
                            newRow = retVal.NewRow();
                            newRow[PKey] = dr[PKey];

                            // Iterate through records and find VALUE for each FIELD column
                            foreach (DataRowView drv in tbl.DefaultView)
                                newRow[Convert.ToString(drv[FKey])] = drv[VKey];

                            retVal.Rows.Add(newRow);
                        }
                    }

                    // Return previous row filter on base table
                    tbl.DefaultView.RowFilter = prevFilter;
                    // Commit chages to Pivot table (if any)
                    retVal.AcceptChanges();
                }
            }
        }
        catch (Exception)
        {

            throw;
        }
        finally
        {
            if (keyTbl != null)
                keyTbl.Dispose();
            if (fldTbl != null)
                fldTbl.Dispose();
        }

        return retVal;
    }

用法很简单,因为它是datatable对象上的扩展方法:

DataTable dt = myTbl.Pivot("DOC_ID", "UI_FIELD", "UI_VALUE");

所以如果mytbl的布局是这样的:

DOC_ID  |  ENTRY_DATE  |  UI_FIELD  |  UI_CAPTION  |  UI_VALUE
----------------------------------------------------------------
  1        01/01/2015    EMPL_NAME    Empl. Name     John Doe
  1        01/01/2015    EMPL_PHONE   Empl. Phone    801-555-1212
  1        01/01/2015    EMPL_MNGR    Empl. Mangr.   Jane Doe

它将返回:

DOC_ID  |  ENPL_NAME  |  EMPL_PHONE  | EMPL_MNGR
-------------------------------------------------
  1        John Doe     801-555-1212   Jane Doe

在垂直行中布局ui条目数据的好处(无论如何在制造环境中)是更好地适应ui字段的增加或减少。。这种情况经常发生!因为您最不想做的就是修改数据模式。尤其是当大约一百个(已知的和未知的)应用程序也在使用它时。
不管怎样,不管它值多少钱,我希望这能引导你朝着理想的方向前进。我经常用这个。

相关问题