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

发布于 2024-08-24 07:32:56 字数 1405 浏览 3 评论 0原文

我认为我需要一种方法来使用 C# 和 Linq 执行具有不确定数量的列的数据透视表或交叉表。不过,我将添加一些开始细节,看看它会走向何方。

<开始详细>>

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

string EventName;
Datetime WhenItHappend;

我们想要生成一个如下例所示的报告,其中我们按事件名称进行分组,然后有一系列计算某些日期和时间范围计数的列。困难显然在于列数的变化。

  体育2010年1月2009年1月2010年2月2009年2月< /kbd>
篮球    26      18    ;   23     16  
曲棍球        28      19  < /kbd>   25      18  
游泳    52      45  < kbd>    48  
    43  

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

有什么方法可以在 C# 中将其组装为单个 linq IQueryable 结果吗?

<结束开始详细>>

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

I think I need a way to perform a pivot or crosstab using C# and Linq with an indeterminate number of columns. However, I will add some beginning detail to see where it goes.

< Beginning detail >

Imagine a table that has two fields:

string EventName;
Datetime WhenItHappend;

We want to generate a report like the example below where we group by the EventName, then have a series of columns that calculate some date and time frame count. The difficulty is obviously a variable number of columns.

  Sport   Jan 2010Jan 2009Feb 2010Feb 2009
Basketball    26      18      23      16  
Hockey        28      19      25      18  
Swimming      52      45      48      43  

The customer can create any number of named event counters for a report. The functions are always the same: "Name", "begin", "end".

Any way to assemble this as a single linq IQueryable result in C#?

< End Beginning detail >

As far as SQL goes, I tried creating a date range table {TimeFrameName, begin, end} and joined that to the above table where begin <= whenItHappened and whenItHappened <= end, which produced a nice set of {EventName, TimeFrameName} then did a count(*), but was still left with how to transform the data, making the rows in to columns.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尐偏执 2024-08-31 07:32:56

您有一个类/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 } );

现在您实际上拥有了一个二维集合数组。您可以对 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 匹配的原始列表的子集。如果指定二维 Key,则可以将结果视为二维集合数组。

GroupBy是一个非常强大的运算符!

You have a class / SQL row

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

and you want to group by EventName and 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 } );

Now you essentially have a 2 dimensional array of collections. You can iterate through these on Month / EventName to get the counts of the items in each collection, which is what you want to display in your table.

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

The GroupBy operator returns a collection of groups, where each group contains a Key and a subset of the original list that match the specified Key. If you specify a 2 dimensional Key, you can treat the result as a 2 dimensional array of collections.

GroupBy is a very powerful operator!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文