2012-04-13 4 views
5

私は、DateTimeフィールドに次のレコードを持つデータベースを持っている:LINQクエリでDateTimeフィールドを平均化するにはどうすればよいですか?

2012-04-13 08:31:00.000 
2012-04-12 07:53:00.000 
2012-04-11 07:59:00.000 
2012-04-10 08:16:00.000 
2012-04-09 15:11:00.000 
2012-04-08 08:28:00.000 
2012-04-06 08:26:00.000 

私は上記の記録から平均時間を取得するために、SQLクエリにLINQを実行したいです。私は以下を試しました:

​​

"SleepTo"はdatetimeフィールドなので、Average()にエラーが発生します。私が整数の平均を取得しようとしていた場合、上記のlinqクエリが機能します。

datetimesで動作させるには、何が必要ですか?

+0

偶然にもSleepFromの値はありますか? – yamen

+0

私はそれのための独自の拡張メソッドを作成しようとします。 – frenchie

答えて

1

データベースLINQプロバイダは、絶対日付に対して平均を行う方法を理解していないようです。あなたがそれについて考えるなら、どちらが意味があるのですか(平均は合計を数で割ったものです - 合計は何ですか?)。だから、

、あなたは次のことを実行することはできません場合:

(From o In MYDATA Select o.SleepTo).Sum()

その後も.Average()を行うことができません。

実際にはの平均時間はSleepToのなので、日付の時間成分だけをTimeSpan(おそらく午前0時から午前0時)とし、その平均値を取得する必要があります。万が一あなたはSleepFromを持っていますか?一方

、あなたは啓発この記事を見つけるかもしれない:内部LINQ Average TimeSpan?

+0

私は合計を試しましたが、それはどちらかの日付を好きではありません。私のサンプルのデータは私が目を覚ました時間です。私は目を覚ました平均時間を取得しようとしています。 – Jade

+0

これは私の要点ですが、合計は機能しません。したがって、平均値も機能しません。あなたの最高のベストは、日のコンポーネントを取り除き、ただ時間を得ることです。それを真夜中からタイムパンに変えれば、平均を得ることができます。これにより、平均起床時間(AM)が得られます。投稿したリンクを参照してください。 – yamen

+0

あなたは 'SleepFrom'を持っているかどうかに関する情報を尋ねる答えを更新しました。つまり、あなたが目を覚ます平均時間、またはあなたが眠っている平均量を知りたいですか? – yamen

8

、すべての日時は本当にチック数として格納されています。 DateTimeのTicksプロパティは、「0001年1月1日午前12:00:00から経過した100ナノ秒の間隔の数」として定義されます。 (http://msdn.microsoft.com/en-us/library/system.datetime.ticks.aspxを参照してください)

DateTimeをダニに変換し、平均してからdatetimeに変換することができます。あなたのデータ構造と書式設定を使用して

var averageTicks = (long) dates.Select(d => d.Ticks).Average(); 
var averageDate = new DateTime(averageTicks); 

、それは次のようになります。

var averageTicks = (long)(from o in MYDATA select o.SleepTo.Ticks).Average(); 
var averageDate = new DateTime(averageTicks); 

あなたは(日付コンポーネントを無視して)各SleepTo値の平均時間を取得したい場合は、あなたが得ることができますちょうど時間の目盛り:

var averageTicks = (long)(from o in MYDATA select o.SleepTo.TimeOfDay.Ticks).Average(); 
var averageTime = new TimeSpan(averageTicks); 
+0

平均的なDateTimeではなく、SleepToの平均*時間*に関連しているため、これは望ましい回答を与えません。真夜中からSleepToをTimeSpanに変換してから真夜中からTicksしてから平均化することをお勧めします。それ以外の場合はすべての答えが間違っています。 – yamen

+0

Jadeのオリジナル記事のコードサンプルと最後の質問は、彼が「DateTime」の平均化に役立つことを求めていると信じてくれました。あなたの提案@yamenに基づいて、私は時間成分だけを平均化するための新しいスニペットを追加しました。ありがとう! –

+0

いい加減、アップしました! – yamen

4

ここでは、これを助けることができるカップルの拡張メソッドです...あなたがリスト内のLINQの平均値を日付時刻の多くを持っている場合、コアの問題がありますダニ(longヴァース)がオーバーフローします。

public static long Average(this IEnumerable<long> longs) 
    { 
     long count = longs.Count(); 
     long mean = 0; 
     foreach (var val in longs) 
     { 
      mean += val/count; 
     } 
     return mean; 
    } 

    public static DateTime Average(this IEnumerable<DateTime> dates) 
    { 
     return new DateTime(dates.Select(x => x.Ticks).Average()); 
    } 
+0

+1。ありがとう。これは、項目の数が十分に多いときに受け入れられた答えの改善です。 – MickyD

+0

ありがとう!ニースの改善! – klutch1991

+0

val/countに整数除算を使用しているので、これがエラーを蓄積する可能性があると思います。あなたの平均を新しい[] {3l、5l、7l}で試してください。正しい平均は5です。あなたは4になります。私はあなたが中間の数学のために倍を使うべきだと思います。私はまたLinqを理解するのが難しいので、Linqを使用することを好む:) public static long Average(this IEnumerable longs){ \t \t var count = longs.Count(); \t \t return(long)(longs.Aggregate(0.0、(r、l)=> r + =(double)l/count)); } – NetMage

関連する問題