2012-07-15 16 views
6

date_trans、time_trans、priceという列を含むテーブルがあります。クエリを選択した後、価格列の連続した等しい値として計算される新しい列「Count」を追加し、連続する等しい価格を持つ前の行が最終結果から削除されます。現在クエリを最適化するか、LINQ相当を提案する

date_trans time_trans price **Count**  
2011-02-22 09:39:59 58.02 1 
2011-02-22 09:40:03 58.1 *ROW WILL BE REMOVED 
2011-02-22 09:40:07 58.1 *ROW WILL BE REMOVED 
2011-02-22 09:40:08 58.1 3 
2011-02-22 09:40:10 58.15 1 
2011-02-22 09:40:10 58.1 *ROW WILL BE REMOVED 
2011-02-22 09:40:14 58.1 2 
2011-02-22 09:40:24 58.15 1 
2011-02-22 09:40:24 58.18 *ROW WILL BE REMOVED 
2011-02-22 09:40:24 58.18 *ROW WILL BE REMOVED 
2011-02-22 09:40:24 58.18 3 
2011-02-22 09:40:24 58.15 1 

選択するために、SQLクエリまたはLINQ式を提案してくださいテーブルから

、私は選択クエリもそれを行うと、選択したすべての行をループすることができますが、何百万人を選ぶとき:期待される出力を参照してください。行の数時間かかる

私の現在のコード:

string query = @"SELECT date_trans, time_trans, price 
          FROM tbl_data 
         WHERE date_trans BETWEEN '2011-02-22' AND '2011-10-21' 
         AND time_trans BETWEEN '09:30:00' AND '16:00:00'"; 

      DataTable dt = oUtil.GetDataTable(query); 

      DataColumn col = new DataColumn("Count", typeof(int)); 
      dt.Columns.Add(col); 

      int priceCount = 1; 
      for (int count = 0; count < dt.Rows.Count; count++) 
      { 
       double price = Convert.ToDouble(dt.Rows[count]["price"]); 
       double priceNext = (count == dt.Rows.Count - 1) ? 0 : Convert.ToDouble(dt.Rows[count + 1]["price"]); 
       if (price == priceNext) 
       { 
        priceCount++; 
        dt.Rows.RemoveAt(count); 
        count--; 
       } 
       else 
       { 
        dt.Rows[count]["Count"] = priceCount; 
        priceCount = 1; 
       } 
      } 
+0

私は、SQLの解析関数を使用することが可能だと思います。遅刻しているので、私の脳はそれをすべて処理することができませんが、私が休んだとき、私は戻ってきて答えが必要かどうかを見ていきます。しかし、私はあなたが[この回答](http://stackoverflow.com/questions/7854854/getting-all-consecutive-rows-differing-by-certain-value)とそれがどのように分析関数を使用するかを見て始めなければならないと思います。 – Ally

答えて

2

興味深いものです。

ここに解決策が見つかり
SELECT MAX(date_trans), MAX(time_trans), MAX(price), COUNT(*) 
FROM 
    (SELECT *, ROW_NUMBER() OVER(PARTITION BY price ORDER BY date_trans, time_trans) - ROW_NUMBER() OVER(ORDER BY date_trans, time_trans) AS grp 
    FROM transactions) grps 
GROUP BY grp 

:私はあなたがこのようなものになるだろう必要なものだと思う

http://www.sqlmag.com/article/sql-server/solution-to-the-t-sql-puzzle-grouping-consecutive-rows-with-a-common-element

UPDATEは、グループ化列は、それ以外のグループではないかもしれない、また、「価格」を含める必要があります一意であること。もう1つのことは、日付と時刻の列をdatetime列に結合して、日付の最大値が、1日の終わり近くに始まり、次の日付の始めに終了するグループで正しいことです。 修正されたクエリは次のとおりです。

SELECT MAX(CAST(date_trans AS DATETIME) + CAST(time_trans AS DATETIME)) , MAX(price), COUNT(*) 
FROM 
    (SELECT *, 
     CAST(ROW_NUMBER() OVER(PARTITION BY price ORDER BY date_trans, time_trans) - ROW_NUMBER() OVER(ORDER BY date_trans, time_trans) AS NVARCHAR(255)) + '-' + CAST(price AS NVARCHAR(255)) AS grp 
    FROM transactions 
    ORDER BY date_trans, time_trans) grps 
GROUP BY grp 

クエリは、「grp」列がnvarcharではなくバイト配列またはbigintとして最適な場合があります。また、グループ内で合計したいと思う「ボリューム」列についても言及しました。

+0

ありがとうPawel。あなたはほとんどそこにいます。 csvをダウンロードし、データベースにインポートして確認してください。一部のレコードが重複して表示されています。あなたの質問を改善して助けてください。 https://docs.google.com/open?id=0B_fUxFgeU2-dc3hfR2JrR2ExQ2s カラムには、date_trans、time_trans、price、CSVのボリューム – Mainuddin

+0

があります。答えを更新しました。私は以前気付かなかったが、あなたはあなたの質問に「mysql」タグをつけたが、あなたは「mssql」を意味したのだろうか? –

+0

修正しました。 –

関連する問題