数据表组和数据透视表

时间:2016-10-12 09:41:50

标签: c# .net

我有一个具有以下结构的DT

unit | value | date
-------------------------
 A   |   2   | 01-01-2000
 B   |   3   | 01-01-2000
 A   |   4   | 02-01-2000

我想将其转换为以下

            |   A   |  B
 ---------------------------
 01-01-2000 |   2   |  3
 02-01-2000 |   4   |

实现这一目标的最快方法是什么?

编辑: 我已经为pivot实现了一个函数,它给了我以下内容:

        |  A       |  B       |  A
--------------------------------------
value   |  2       |  3       |  4
date    |01-01-2000|01-01-2000|02-01-2000

但在这种情况下,我缺少按列分组。

最快'我的意思是可能是实现这个的最短代码(LINQ?)。或者也许可以在同一个查询中同时实现数据透视?

2 个答案:

答案 0 :(得分:1)

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("unit", typeof(string));
            dt.Columns.Add("value", typeof(int));
            dt.Columns.Add("date", typeof(DateTime));

            dt.Rows.Add(new object[] { "A",2, DateTime.Parse("01-01-2000")});
            dt.Rows.Add(new object[] { "B",3, DateTime.Parse("01-01-2000")});
            dt.Rows.Add(new object[] { "A",4, DateTime.Parse("02-01-2000")});

            string[] uniqueUnits = dt.AsEnumerable().Select(x => x.Field<string>("unit")).Distinct().ToArray();

            DataTable dt1 = new DataTable();
            dt1.Columns.Add("date", typeof(DateTime));
            foreach (string unit in uniqueUnits)
            {
                dt1.Columns.Add(unit, typeof(int));
            }
            var groups = dt.AsEnumerable().GroupBy(x => x.Field<DateTime>("date"));

            foreach (var group in groups)
            {
                DataRow newRow = dt1.Rows.Add();
                foreach (DataRow row in group)
                {
                    newRow["date"] = group.Key;
                    newRow[row.Field<string>("unit")] = row.Field<int>("value");
                }
            }
        }
    }
}

enter image description here

答案 1 :(得分:0)

它有更多的代码行,但也可以只用一个循环来完成:

        DataTable dt1 = new DataTable();
        dt1.Columns.Add(new DataColumn("unit",typeof(string)));
        dt1.Columns.Add(new DataColumn("value",typeof(int)));
        dt1.Columns.Add(new DataColumn("date",typeof(DateTime)));

        dt1.Rows.Add(new object[] { "A", 2, DateTime.Parse("01-01-2000") });
        dt1.Rows.Add(new object[] { "B", 3, DateTime.Parse("01-01-2000") });
        dt1.Rows.Add(new object[] { "A", 4, DateTime.Parse("02-01-2000") });

        DataTable dt2 = new DataTable();
        dt2.Columns.Add(new DataColumn("date", typeof(DateTime)));
        dt2.PrimaryKey = new DataColumn[] { dt2.Columns["date"], };
        List<string> cols = new List<string>();
        List<DateTime> ds = new List<DateTime>();
        foreach (DataRow dr1 in dt1.Rows)
        {
            string unit = dr1["unit"].ToString();
            if (!cols.Contains(unit))
            {
                dt2.Columns.Add(new DataColumn(unit, typeof(int)));
                cols.Add(unit);
            }
            DateTime pkDate = (DateTime)dr1["date"];
            if (!ds.Contains(pkDate))
            {
                ds.Add(pkDate);
                DataRow dr = dt2.NewRow();
                dr["date"] = dr1["date"];
                dr[unit] = dr1["value"];
                dt2.Rows.Add(dr);
            }
            else
            {
                dt2.Rows.Find(pkDate)[unit] = dr1["value"];
            }
        }