Linq:如何将行转换为带有计数的列(交叉表数据)?

时间:2010-03-08 22:22:10

标签: c# linq crosstab

我认为我需要一种方法来使用C#和Linq以不确定数量的列执行数据透视表或交叉表。但是,我会添加一些开头细节,看看它的位置。

<开始详细信息>

想象一下有两个字段的表:

string EventName;
Datetime WhenItHappend;

我们希望生成一个类似下面示例的报告,我们按EventName进行分组,然后有一系列用于计算某些日期和时间帧数的列。困难显然是可变数量的列。

Sport 2010年1月 2009年1月 2010年2月 2009年2月
篮球 26 18 23 16
曲棍球 28 19 25 18
游泳 52 45 48 43

客户可以为报告创建任意数量的命名事件计数器。功能始终相同:“名称”,“开始”,“结束”。

有什么方法可以将它作为单个linq IQueryable结果汇总到C#中?

<结束开始详细信息>

就SQL而言,我尝试创建一个日期范围表{TimeFrameName,begin,end}并将其连接到上面的表,其中begin< = whenItHappened和whenItHappened< = end,这产生了一组很好的{ EventName,TimeFrameName}然后做了一个count(*),但仍然留下了如何转换数据,使行成为列。

1 个答案:

答案 0 :(得分:2)

你有一个类/ SQL行

class Thing
{
    public string EventName;
    public DateTime WhenItHappend;
}

并且您希望按EventName和WhenItHappened.Month

进行分组
// make a collection and add some Things to it
var list = new List<Thing>();
list.Add(new Thing(){ .... });
// etc

var groups = list.GroupBy(t => new { t.WhenItHappend.Month, t.EventName } );

现在你基本上有一个2维的集合数组。您可以在Month / EventName上迭代这些,以获取每个集合中项目的计数,这是您希望在表格中显示的内容。

foreach (var row in groups.GroupBy(g => g.Key.EventName))
{
    foreach (var month in row.GroupBy(g => g.Key.Month))
    {
        var value = month.Count();
    }
}

GroupBy运算符返回一组组,其中每个组包含一个Key以及与指定Key匹配的原始列表的子集。如果指定2维键,则可以将结果视为2维数组的集合。

GroupBy是一个非常强大的运营商!