4

私は大きなデータテーブル(500k-1m行)を持っていますが、詳細には触れませんが、エンドユーザーがすべてのデータを表示できるようにする必要があるため、これは要件です。これはローカルサーバー上にあるので、帯域幅などは私には関係ありません。

DataTableにグループ化する必要のあるDateTimeフィールドがあります。グループ化の意味を説明しましょう...おそらく、私が意味しているとは思わないでしょう(ここで他の質問を見てください!)。

        var table = new DataTable();
        table.Columns.Add("EventTime", typeof(DateTime));
        table.Columns.Add("Result", typeof(String));
        table.Columns.Add("ValueOne", typeof(Int32));
        table.Columns.Add("ValueTwo", typeof(Int32));
        table.Rows.Add("2012-02-06 12:41:45.190", "A", "7", "0");
        table.Rows.Add("2012-02-06 12:45:41.190", "B", "3", "89");
        table.Rows.Add("2012-02-06 12:59:41.190", "C", "1", "0");
        table.Rows.Add("2012-02-06 13:41:41.190", "D", "0", "28");
        table.Rows.Add("2012-02-06 17:41:41.190", "E", "0", "37");
        table.Rows.Add("2012-02-07 12:41:45.190", "F", "48", "23");

上記のテーブルをグループ化して、「ValueOne」列の合計と「ValueTwo」列の平均を取得することを期待します。分単位(最初と最後の行のみがグループ化され、残りは値を提供するだけ)または日数(最後の行を除くすべて)でグループ化するように指定できるように、グループ化を少し柔軟にする必要があります1つの行にグループ化されます)など。

私はこれを数回試しましたが、どこにも行きません。私のLINQの知識はあまり良くありませんが、私はこれができると思いました!

注:DataTableは、変更できない計算/ビュー用のマシン上にすでに存在するため、「ばかげたことをやめて、SQLでフィルター処理してください!!!」と言います。有効な答えですが、私には役に立たないのです!:-D

また、タイトルで見逃した場合は、C#でこれが必要です-私は.NET4.0で作業しています...

あなたが助けることに決めたと仮定して、事前に感謝します!:-)

4

4 に答える 4

5

他の3つの答えは近いですが、あなたが指摘したように、それらは同じ秒に発生したイベントではなく、同じ秒に発生したイベントをグループ化します。これはあなたが望むものです。これを試して:

var query = from r in table.Rows.Cast<DataRow>()
        let eventTime = (DateTime)r[0]
        group r by new DateTime(eventTime.Year, eventTime.Month, eventTime.Day, eventTime.Hour, eventTime.Minute, eventTime.Second)
            into g
        select new {
                g.Key,
                Sum = g.Sum(r => (int)r[2]),
                Average = g.Average(r => (int)r[3])
            };

DateTime コンストラクターに渡す情報を調整して、さまざまな時間部分でグループ化できます。

于 2012-04-03T20:55:48.290 に答える
1

変更する必要があるのは、グループ化するプロパティだけです。

var query = from x in DataSource
            group x by x.EventTime.Minute into x
            select new
            {
              Unit = x.Key,
              SumValueOne = x.Sum(y => y.ValueOne),
              AverageValueTwo = x.Average(y => y.ValueTwo), 
            };
于 2012-04-03T20:32:28.627 に答える
1

このようなものが動作するはずです:

DataTable dt = GetDataTableResults();

var results = from row in dt.AsEnumerable()
              group row by new { EventDate = row.Field<DateTime>("EventTime").Date } into rowgroup
              select new
              {
                  EventDate = rowgroup.Key.EventDate,
                  ValueOne = rowgroup.Sum(r => r.Field<int>("ValueOne")),
                  ValueTwo = rowgroup.Average(r => r.Field<decimal>("ValueTwo"))
              };  
于 2012-04-03T20:38:18.407 に答える
0

ベースライン コードは次のようになります。

var query = table.Rows.Cast<DataRow>()
    .GroupBy(r => ((DateTime)r[0]).Second)
    .Select(g => new
                 {
                    g.Key, 
                    Sum = g.Sum(r => (int)r[2]),
                    Average = g.Average(r => (int)r[3])
                 });

柔軟性を追加するには、次のようなものがあります。

IEnumerable<IGrouping<object, DataRow>> Group(IEnumerable<DataRow> rows, GroupType groupType)
{
    // switch case would be preferable, but you get the idea.
    if(groupType == GroupType.Minutes) return rows.GroupBy(r => ((object)((DateTime)r[0]).Minute));
    if(groupType == GroupType.Seconds) return rows.GroupBy(r => ((object)((DateTime)r[0]).Second));
    ...
}

var baseQuery = table.Rows.Cast<DataRow>();
var grouped = Group(baseQuery, groupType);
var query = grouped
    .Select(g => new
                 {
                    g.Key, 
                    Sum = g.Sum(r => (int)r[2]),
                    Average = g.Average(r => (int)r[3])
                 });
于 2012-04-03T20:38:41.837 に答える