2017-01-11 4 views
1

私は次のようなデータを持つ非常に単純な注文のテーブルを持っている:私は[Timestamp]秩序を壊すことなくSELECT MAX([Timestamp]), Count FROM [dbo].[Table] GROUP BY [Count]したい注文を破らずにGROUP BYするには?

============================= 
| Timestamp | Count | 
============================= 
| 12/30/2016 | 322  | 
| 12/29/2016 | 322  | 
| 12/28/2016 | 322  | 
| 12/4/2016 | 541  | 
| 12/3/2016 | 541  | 
| 12/2/2016 | 541  | 
| 12/1/2016 | 322  | 
| 11/30/2016 | 322  | 
| 11/29/2016 | 322  | 
============================= 

出力があるべきすなわち:

============================= 
| Timestamp | Count | 
============================= 
| 12/30/2016 | 322  | 
| 12/4/2016 | 541  | 
| 12/1/2016 | 322  | 
============================= 

ので12/1/2016 | 322がで隠されていませんGROUP BY。 誰もそのようなクエリを書く方法を知っていますか?私はEntityFrameworkのLinqクエリが必要で、T-SQLのアナログを知ることは素晴らしいことです。

+0

カウントとgeting maxによるグループは動作しませんか? – Damirchi

+0

@Damirchi noは、第2の「322」の値を隠すため、 – dyatchenko

+0

あなたは「各カウントの最大タイムスタンプ」と言っていますが、ほとんどは322ではありません。 – Damirchi

答えて

3

私はあなたがこのようなクエリが必要だと思う:私は前の回答を参照してください

select [Timestamp], [Count] 
from (
    select * 
     --//Step 3: Now just find the max value 
     , row_number() over (partition by seqGroup order by [Timestamp] desc) as seq 
    from (
     select * 
      --//Step 2: you need to generate a group number for each sequence 
      , sum(changed) over (order by [Timestamp] desc) as seqGroup 
     from (
      select * 
       --//Step 1: you need to track changes over [Count] 
       , case when coalesce(lag([Count]) over (order by [Timestamp] desc), [Count]) = [Count] then 0 else 1 end as changed 
      from yourTable) t1 
     ) t2 
    ) t3 
where seq = 1; 
+0

このクエリのように見えます。どうもありがとう。あなたLinqアナログを知っていますか? – dyatchenko

+0

私はLinQを本当にうまく使っていませんが、今ではLinQを要求できます。 –

0

、および彼の基礎書かれたLINQのご要望に応じて。

1)あなたはinitTable作成:

var initTable = new List<Tuple<DateTime, int>>(); 
       initTable.Add(Tuple.Create(new DateTime(2016, 12, 30), 322)); 
       initTable.Add(Tuple.Create(new DateTime(2016, 12, 29), 322)); 
       initTable.Add(Tuple.Create(new DateTime(2016, 12, 28), 322)); 
       initTable.Add(Tuple.Create(new DateTime(2016, 12, 4), 541)); 
       initTable.Add(Tuple.Create(new DateTime(2016, 12, 3), 541)); 
       initTable.Add(Tuple.Create(new DateTime(2016, 12, 2), 541)); 
       initTable.Add(Tuple.Create(new DateTime(2016, 12, 1), 322)); 
       initTable.Add(Tuple.Create(new DateTime(2016, 11, 30), 322)); 
       initTable.Add(Tuple.Create(new DateTime(2016, 11, 29), 322)); 

2) initTableに行インデックスを追加して、タイムスタンプ順:

//get row index 
var table = initTable 
      .Where(x => true) 
      .Select((x, i) => new 
      { 
       Timestamp = x.Item1.ToString("MM-dd-yyyy"), 
       Count = x.Item2, 
       //row index 
       Index = i 
      }) 
      .OrderByDescending(x => x.Timestamp); 

3)クエリ

var query = table 
      //#1 get prev row count 
      .Select(x => new 
      { 
       x.Timestamp, 
       x.Count, 
       x.Index, 
       //previous row count (-1 for first row, not default null) 
       Prev = table.LastOrDefault(y => y.Index < x.Index) == null ? 
         -1 : 
         table.LastOrDefault(y => y.Index < x.Index).Count 
      }) 
      //#2 set group flag 
      .Select(x => new 
      { 
       x.Timestamp, 
       x.Count, 
       x.Index, 
       x.Prev, 
       GroupId = x.Count == x.Prev 
      }) 
      //#3 
      .Where(x => x.GroupId == false) 
      .Select(x => new 
      { 
       x.Timestamp, 
       x.Count 
      }); 

LinqPadに挿入して結果を確認できます。

これは役に立ちそうです。