2011-08-02 46 views
1

私は大量のデータをスライスするのにC#とSQLiteを使用しています。私はしばしばピボットテーブル形式でデータを表示する必要があります。私は他のクエリからSQLコマンドを作成するためにC#を使用してピボットを動的に簡単にすることができますが、ピボット自体をどのように行うかを決めることができないので、私..SQLiteでピボットテーブルを実行する最も良い方法は?

私は3つの方法を念頭に置いています。 「行」はそのデータの行番号を表し、「col」は列番号を表し、「val」は値を表します。

オーソドックスな方法は、CASE式を使用することです:

SELECT 
     row, 
     sum(CASE col WHEN 1 THEN val END) AS col1, 
     sum(CASE col WHEN 2 THEN val END) AS col2, 
     sum(CASE col WHEN 3 THEN val END) AS col3 
FROM tData 
GROUP BY row 

しかし、私は事実を利用し、私はCASE文を捨てるならば、多分それがより速くなる可能性があり、値を直接論理式を使用して考えていました真== 1とfalse == 0:

SELECT 
     row, 
     sum((col=1)*val) AS col1, 
     sum((col=2)*val) AS col2, 
     sum((col=3)*val) AS col3 
FROM tData 
GROUP BY row 

私はCASE式は、いくつかのオーバーヘッドを持っていなければならないので、この方法は、より高速でなければなりません疑うが、私は本当にわかりません。

第三の方法は少し複雑です:それは使用しています旋回を行うために結合します

SELECT 
     rows.row, 
     col1.valSum AS col1, 
     col2.valSum AS col2, 
     col3.valSum AS col3 
FROM 
    (SELECT row FROM tData GROUP BY row) AS rows 
LEFT JOIN 
    (SELECT row,sum(val) AS valSum FROM tData WHERE col=1 GROUP BY row) AS col1 
    ON rows.row=col1.row 
LEFT JOIN 
    (SELECT row,sum(val) AS valSum FROM tData WHERE col=2 GROUP BY row) AS col2 
    ON rows.row=col2.row 
LEFT JOIN 
    (SELECT row,sum(val) AS valSum FROM tData WHERE col=3 GROUP BY row) AS col3 
    ON rows.row=col3.row 

真、それらは深刻なオーバーヘッドを持ってJOINのが、私の限られた経験から、大きなテーブルのSQL実装とすることができます扱うとき単純なフィルタグループとサムの操作は、カスタムデータ操作の各行の操作よりもはるかに高速で、そのオーバーヘッド以上のものを実行します。 問題は、これらの種類のSQL文は、それぞれの列が文の2桁(フィールド句とFROM句の両方に表示されるため、最初の2つメソッド。また、私はそれらのすべての一時テーブルの名前に注意する必要があります。

だから、意見はありますか?

答えて

1

質問文の中に別個の値があるので、ケース・ステートメントのアプローチは、テーブルに対して多くのグループ・バイ・アンド・ジョインを行うよりも迅速に実行することが期待されます。前者はCPU集約型で、後者はディスク集約型です。例えば。列ヘッダーになる列の値に曜日が含まれている場合は、7つのピボット列と7つの選択-groupbysがあります。それは高価かもしれません。それはテーブルのサイズに依存します。

0

EAVデザインを使用しているようですが、行を列にピボットする必要があります。適切なリレーショナルデータベース設計では、EAVを使用しません。列は列であり、ピボットする必要はありません。

私は、EAVは時には邪悪なものではなく、拡張可能な属性のセットをデータベースに保存する必要があるときには人気のあるデザインだと理解しています。

データを戻す最も効率的な方法は、SQLでピボットを行うことを忘れることです。ちょうどrowの所与の値ごとに複数の行として、あなたの属性をフェッチ:

SELECT row, col, val FROM tData WHERE row = ... 

その後、得られた複数行の結果セットをループへのC#アプリケーションのコードを書きます。個別のrowごとに新しいオブジェクトを作成します。オブジェクトのcolフィールドを値valに設定します。その後、クエリ結果の次の行を引き続き取得します。

これは利点があります:

  • クエリを書くのは簡単です。選択リストには3つの列しか指定できません。列の別名は必要ありません。
  • RDBMSを実行するには、クエリが安価です。いいえGROUP BY、セルフジョインはありません。
  • EAVデザインの拡張可能なメリットを引き続きサポートします。実際には、データに新しい論理列を追加するときにSQLクエリを書き直す必要がないため、拡張が容易です。
+0

私はEAVを使用しません。 col1、col2、col3には本質的な違いはありません。たとえば、異なる日付にすることができます。ピボットSQLクエリが欲しい唯一の理由は、Excelスプレッドシートでクライアントに表示できるようにすることです。 私はピボットをハードコーディングすることを考えましたが、SQLをXMLファイルに入れたいので、同じプログラムを使用して別のXMLをロードし、別のデータをスライスすることができます。 –

関連する問題