2

これは、私の最初の実際の LINQ-to-SQL クエリです。大きな明らかな間違いを犯しているのではないかと思っていました。

データ、dataTypeID、machineID、dateStamp を含む中規模 (2M 以上のレコード、1 日に 13k を追加) のテーブルがあります。28 日間さかのぼって、4 時間以内にすべてのマシンと特定のデータ型のデータの平均、最小、最大を取得したいと考えています。

例えば

DateTime Avg Min Max
1/1/10 12:00AM 74.2 72.1 75.7
1/1/10 04:00AM 74.5 73.1 76.2
1/1/10 08:00AM 73.7 71.5 74.2
1/1/10 12:00PM 73.2 71.2 76.1
など.
1/28/10 午前 12:00 73.1 71.3 75.5

これまでのところ、平均を 1 時間ごとにグループ化することしかできませんでしたが、代替案が非常に乱雑な場合は、おそらくそれで対処できます。

コード:

var q =
    from d in DataPointTable
    where d.dateStamp > DateTime.Now.AddDays(-28) && (d.dataTypeID == (int)dataType + 1)
    group d by new {
        d.dateStamp.Year,
        d.dateStamp.Month,
        d.dateStamp.Day,
        d.dateStamp.Hour
    } into groupedData
    orderby groupedData.Key.Year, groupedData.Key.Month, groupedData.Key.Day, groupedData.Key.Hour ascending
    select new {
        date = Convert.ToDateTime(
            groupedData.Key.Year.ToString() + "-" +
            groupedData.Key.Month.ToString() + "-" +
            groupedData.Key.Day.ToString() + " " + 
            groupedData.Key.Hour.ToString() + ":00"
            ),
        avg = groupedData.Average(d => d.data),
        max = groupedData.Max(d => d.data),
        min = groupedData.Min(d => d.data)
    };
4

1 に答える 1

3

4 時間の増分が必要な場合は、時間を 4 で割り (整数除算を使用)、新しい datetime 要素を作成するときに 4 を掛けます。文字列を作成して変換する代わりに、年、月、日、時、分、秒を受け取るコンストラクターを使用できることに注意してください。

var q = 
    from d in DataPointTable 
    where d.dateStamp > DateTime.Now.AddDays(-28) && (d.dataTypeID == (int)dataType + 1) 
    group d by new { 
        d.dateStamp.Year, 
        d.dateStamp.Month, 
        d.dateStamp.Day, 
        Hour = d.dateStamp.Hour / 4
    } into groupedData 
    orderby groupedData.Key.Year, groupedData.Key.Month, groupedData.Key.Day, groupedData.Key.Hour ascending 
    select new { 
        date = new DateTime(
            groupedData.Key.Year, 
            groupedData.Key.Month, 
            groupedData.Key.Day, 
            (groupedData.Key.Hour * 4),
            0, 0), 
        avg = groupedData.Average(d => d.data), 
        max = groupedData.Max(d => d.data), 
        min = groupedData.Min(d => d.data) 
    };

効率を向上させるには、dateStamp列にインデックスを追加することを検討してください。可能性のある小さな範囲の日付のみを選択していることを考えると、インデックスを使用すると大きな利点が得られます。クエリ プランが最初の日付のインデックス シークを実行して、さらに高速化することを期待します。

于 2010-02-18T18:59:52.313 に答える