2009-07-09 11 views
0

これは簡単で一般的なシナリオです。入力していただければ幸いです。行と列の依存性を説明する

私はペットショーのオーナーのためのレポートを作成しており、どの顧客がどれくらい多くのペットを購入したのか知りたいとします。このシナリオで私の唯一のツールは、SQLと私のクエリをスプレッドシートに出力するものです。店のオーナーとして

、私は形式でレポートを期待するかもしれない:

Customer Dog Cat Rabbit 
1   2 3 0 
2   0 1 1 
3   1 2 0 
4   0 0 1 

そしてある日、私は金魚をストックすることを決定した場合、その後の報告は今のように出てくるはずです。

Customer Dog Cat Rabbit Goldfish 
1   2 3 0  0 
2   0 1 1  0 
3   1 2 0  0 
4   0 0 1  0 
5   0 0 0  1 

しかし、あなたが知っているように、この方法で動作するクエリを作成するには、何らかの形の動的コード生成が必要となり、やりにくくなります。

最も単純なクエリはの線に沿って働くだろう

: クロスは、顧客やペットを外部結合は、販売に参加、グループなど と生成:

Customer Pet  Quantity 
1  Dog  2 
1  Cat  3 
1  Rabbit 0 
1  Goldfish 0 
2  Dog  0 
2  Cat  1 
2  Rabbit 1 
...etc 

a)はどのように私は店の所有者に説明します彼らが望むレポートは生成するのが「難しい」ということですか?私は読むのが難しいと言っているわけではありませんが、書くのは難しいです。

b)お客様に説明しようとしているコンセプトの名前は何ですか(私のグーグルリングを助けるために)?

+0

Google –

答えて

2

概念の名前は「クロスタブ」であり、いくつかの方法で達成できます。

MS Accessには、これを実現するためにSQLに独自の拡張機能があります。 SQL pre-2k5にはCASEトリックがあり、2k5以降にはPIVOTがありますが、列の内容を知る必要があると思います。

+0

のGoogle「PIVOT」はい、CASEトリックはQuartersのようなものでは機能しますが、このようなものでは機能しません。 –

+0

なぜですか? '四半期'や '犬/猫/ウサギ'のようなものは同じものです。 – n8wrl

+0

四半期は常に4です。売っている動物は必ずしも3つではない –

1

いくつかのデータベースは実際にクロステーブルを作成するいくつかの方法をサポートしていますが、あらかじめカラムを にあらかじめ知っておく必要があると思いますので、SQLを変更する必要があります。

もう1つの方法は、クライアントにクロステーブルを出力するための2番目の「簡単な」テーブルを後処理するプログラムを作成することです。これはおそらく、SQLを変更したり、動的に生成したりするよりも簡単で汎用的です。

  • ソースデータ(2番目のリスト):

    、問題を説明するための方法について...あなたは、所望の結果を得るために必要とされているどのように多くの手順Excelでそれらを示すことができました。ペット列から

  • 値を選択し
  • 置き、クライアントごとの各タイプごとに
  • カウント値
  • は値

を記入して、SQLはあなたを与えることを言う新しい列で見つかった各ペットの種類ソースデータだけですので、もちろんそれ以上の作業です。

1

この概念は、

SQLpivotingは、あなたのデータが固定された構造を持つ関係で表現されていることを前提と呼ばれています。

同様に、等価は2進関係であり、「顧客はこのタイプのペットを多数保有している」というのは3項関係などである。

あなたがこのResultSetを参照する場合:

Customer Pet  Quantity 
1  Dog  2 
1  Cat  3 
1  Rabbit 0 
1  Goldfish 0 
2  Dog  0 
2  Cat  1 
2  Rabbit 1 

を、それが実際にこのような関係にあることドメイン値のすべての可能な組み合わせによって定義された関係です。

と同様に、顧客1(ドメインcustomers id'sは)属dog(ドメインpets)の正確2(ドメインpositive numbers)のペットを持っています。

私たちは、結果セットにこれらのような行が表示されない:

Customer Pet  Quantity 
1  Dog  3 
Pete  Wife  0.67 

、最初の行が(顧客13dogの項目が、2を持っていない)偽、2行目であるため、値はドメインスコープ外です。

SQL paradigmaは、クエリを発行するときにリレーションが定義され、返された各行によってリレーションが完全に定義されることを意味します。

SQL Server 2005+は、行を列にマップすることができますが、クエリを設計するとき(実行していない場合)は列の数を知っておく必要があります。

通常、作成しようとしているレポートは、関係性のあるSQL結果セットを見やすい人間が読めるレポートに変換する方法を知っているレポートソフトウェアで構築されています。

+0

SQL Server固有の用語テーブルは一般的なものですか? –

1

私はいつもこのピボットを呼びましたが、それは正式な名前ではないかもしれません。

これが何であれ、ほとんどすべてをプレーンSQLで処理できます。

SELECT customer, count(*), sum(CASE WHEN pet='dog' THEN 1 ELSE 0 END) as dog, sum(case WHEN pet='cat' THEN 1 ELSE 0 END) as cast FROM customers join pets 

もちろん、欠けているのは動的列です。私はこれがまっすぐSQLでは可能かどうかはわかりませんが、ストアドプロシージャでは、最初にペットのリストを照会した後でクエリを動的に生成することは可能です。クエリは文字列に組み込まれ、その文字列はプリペアドステートメントを作成するために使用されます。

関連する問題