0

こんにちは、次のフィールドを持つデータテーブルがあります

DAT_START
GROUPBY
TXT_LATITTUDE
TXT_LONGITUDE
INT_DIRECTION
INT_CALL_DATA_TYPE
LNG_DURATION

そして、以下は私が使用しているLINQクエリです

var data = (from r in dt.AsEnumerable()
where ((r.Field<DateTime>("DAT_START").TimeOfDay.Hours < 20) && (r.Field<DateTime>("DAT_START").TimeOfDay.Hours >= 4))
group r by new { CID = r["GroupBy"], CLatitude = r["TXT_LATITUDE"], CLongitude = r["TXT_LONGITUDE"],CDirection = r["INT_DIRECTION"], 
CCallType = r["INT_CALL_DATA_TYPE"],CDuration = r["LNG_DURATION"] }
into groupedTable
select new
{
   CellID = groupedTable.Key.CID,
   CallCount = groupedTable.Count(),
   Longitude = groupedTable.Key.CLongitude,
   Latitude = groupedTable.Key.CLatitude,
   Direction = groupedTable.Key.CDirection,
   CallType = groupedTable.Key.CCallType,
   Duration = groupedTable.Key.CDuration
}).OrderByDescending(s => s.CallCount);

このような結果が得られます

CellID = 4057,CallCount = 84,Longitude = "",Latitude = "",Direction = "Incoming",CallType = "Voice",Duration = 50
CellID = 4057,CallCount = 8,Longitude = "",Latitude = "",Direction = "Outgoing",CallType = "Voice",Duration =97
CellID = 4057,CallCount = 56,Longitude = "",Latitude = "",Direction = "Incoming",CallType ="SMS" ,Duration = 0
CellID = 4057,CallCount = 41,Longitude = "",Latitude = "",Direction = "Outgoing",CallType = "SMS",Duration = 0

今、私はこのような結果が欲しい

CellID = 4057, TotalCommCount = 204, TotalDuration = 147, INSMSCount = 56,OutSMSCount = 41, INVoiceCount = 84,OutVoiceCount = 8,InVoiceDuration =50,OutVoiceDuration = 47

これどうやってするの。ここで打ちのめされる..

4

2 に答える 2

6

現時点ではグループ化しすぎているようです。そのため、複数の行が表示されています。次のようなものが必要だと思います:

from r in dt.AsEnumerable()
where r.Field<DateTime>("DAT_START").TimeOfDay.Hours < 20 && 
      r.Field<DateTime>("DAT_START").TimeOfDay.Hours >= 4
group r r["GroupBy"] into g         
select new
{
    CellID = g.Key,
    TotalCommCount = g.Count(),
    TotalDuration = g.Sum(r => r.Field<long>("LNG_DURATION")),
    InSMSCount = g.Count(r => r.Field<string>("DIRECTION") == "Incoming" &&
                              r.Field<string>("CALL_TYPE") == "SMS"),
    OutSMSCount = g.Count(r => r.Field<string>("DIRECTION") == "Outgoing" &&
                               r.Field<string>("CALL_TYPE") == "SMS"), 
    InVoiceCount = g.Count(r => r.Field<string>("DIRECTION") == "Incoming" &&
                                r.Field<string>("CALL_TYPE") == "Voice"),
    OutVoiceCount = g.Count(r => r.Field<string>("DIRECTION") == "Outgoing" &&
                                 r.Field<string>("CALL_TYPE") == "Voice"),
    InVoiceDuration = g.Where(r => r.Field<string>("DIRECTION") == "Incoming" &&
                                r.Field<string>("CALL_TYPE") == "Voice")
                       .Sum(r => r.Field<long>("DURATION"))
    OutVoiceDuration = g.Where(r => r.Field<string>("DIRECTION") == "Outgoing" &&
                                    r.Field<string>("CALL_TYPE") == "Voice"),
                       .Sum(r => r.Field<long>("DURATION"))
 } into summary
 order by summary.TotalCommCount descending
 select summary;
于 2013-05-14T06:24:11.503 に答える
0

必要なものを簡単に集計できるビューを SQL データベースに作成し、そのビューを Linq クエリで使用することをお勧めします。これは高速に実行され、簡単に記述できます。

デザインのスケッチ:

要件の説明が完全に明確ではないため、私は仮定を立てました。次のようなSQL ビューを作成します(アイデアを示すだけで、必要に応じて変更します)。

CREATE VIEW [dbo].[vSumDurations]
AS 
select  c.CellId, j1.SumDuration1 as TotalDuration, 
        j2.SumDuration2 as GroupedDuration, j1.CallCount  
from (select distinct t.CID as CellId from [dbo].[YourTable] t) c
left join (select t1.CID as CellId, sum(LNG_Duration) as SumDuration1, 
            count(*) as CallCount from [dbo].[YourTable] t1 
            Group By t1.CID) j1 
on c.CellId=j1.CellId           
left join (select t2.CID as CellId, sum(LNG_Duration) as SumDuration2 
            from [dbo].[YourTable] t2 
            Group by t2.CID, t2.Direction, t2.CallType) j2 
on c.CellId=j2.CellId

(エンティティ ダイアグラム ページのコンテキスト メニューで [データベースからモデルを更新] を使用して、このビューを *.EDMX に簡単に追加し、ダイアログの [テーブル/ビュー] セクションでビュー vSumDurations にチェックマークを付けることができます。ポップアップします。)

この準備の後、Linq クエリは非常に単純になります。これは、ビューですべてが既に行われているためです。したがって、コードは次のようになります。

var dc = this; // in LinqPad you can set your data context
var data = (from d in dc.vSumDurations select d).OrderByDescending(s => s.CallCount);
data.Dump();

注:この例はLinqPad用に作成されています。実際のコードでは別のデータ コンテキストが必要になります。Linqpad は を必要としませんがdc、実際のコードではそれを提供する必要があるため、便宜上の理由で宣言する方が簡単です。

于 2013-05-14T06:24:19.333 に答える