2011-01-06 11 views
32

私は何かを整理するのに少し助けが必要ですが、私はそれは非常に簡単な質問ですが、それはSQLで私を少し混乱させるものです。GROUP BY/SQLの集約関数の混乱

このSQLクエリは、Oracleでは「NOT GROUP BY式」エラーをスローします。なぜタプルの属性でグループ化すると、他の属性にアクセスすることができなくなることがわかっているように私は理解しています。

SELECT * 
FROM order_details 
GROUP BY order_no 

しかしこれはタプルIグループと、作られる各注文のORDER_DETAILS内に複数のタプルがあると仮定すると....ちょうどこの上で私の理解をコンクリートに

SELECT SUM(order_price) 
FROM order_details 
GROUP BY order_no 

に動作しますorder_noによれば、グループ内の個々のタプルのorder_price属性にはまだアクセスできますが、集計関数を使用するだけですか?

つまり、SELECT句で使用される集約関数は、グループにドリルダウンして「隠し属性」を参照することができます。単に「SELECT order_no」を使用するとエラーがスローされます。

これを明確にするお手伝いをしていただきありがとうございます。Googleでこの特定の質問に対する回答を見つけることが困難でした。あなたはGROUP BYを使用するときにクリス

答えて

34

は、標準のSQL(ただし、MySQLの)では、あなたは、GROUP BY句の集計ではありませんすべての結果列をリストする必要があります。したがって、order_detailsに6列がある場合、GROUP BY句の中で6つの列すべてを(名前によってはGROUP BY句またはORDER BY句に*を使用することはできません)リストする必要があります。

また、行うことができます。すべての非集計列をGROUP BY句にリストされているので、動作します

SELECT order_no, SUM(order_price) 
    FROM order_details 
GROUP BY order_no; 

あなたが何か行うことができます:

SELECT order_no, order_price, MAX(order_item) 
    FROM order_details 
GROUP BY order_no, order_price; 

をこのクエリは本当に意味がありません(またはおそらく意味がありません)が、それは「仕事」になります。別々の注文番号と注文価格の組み合わせがリストされ、その価格に関連付けられた最大注文項目(番号)が表示されます。オーダー内のすべてのアイテムの価格が異なる場合は、それぞれ1行のグループになります。 OTOHでは、同じ価格(例えば、それぞれ£0.99)で注文にいくつかの項目がある場合、それらをまとめてグループ化し、その価格で最大注文項目数を返します。 (テーブルの主キーがであると仮定しています。最初のアイテムはorder_item = 1、2番目のアイテムは2などです)

+0

OK、GROUP BYを実行した後も、特定のorder_noの個々のタプルは、集計関数によって引き続きアクセス可能です。つまり、これらのタプルはorder_noでグループ化されていても、SUM関数は各タプルのorder_price属性にアクセスできますか? – Chris

+5

@Chris:はい、多かれ少なかれ。 GROUP BYは、テーブル内の行をグループに分けて考えることができます。各グループには、GROUP BY句にリストされている列と同じ値のセットがあります。集計は、指定された列のいずれかで操作され、集計はグループ内の行に基づいて計算されます。結果は、GROUP BY列の値に関連する集計を加えた1グループあたり1行で構成されます。ハムム...私はそれがはっきりしていることを願って... –

+0

それは完全に私が言うことができる限りそれをクリアしています。おかげさまでジョナサンと他の人に感謝しました。 – Chris

0

group by句を使用するには、select group by句には文が含まれていますが、aggregate関数の列は含まれていません。

これをグループの代わりに行うには、partition by節を使用できます。これは、1つのポートのみを使用してパーティションとしてグループ化できます。

はまた、あなたは、そのようなものではないグループにエラーを投げることのすべての列を選択している上記のクエリでは1

0
SELECT * 
FROM order_details 
GROUP BY order_no 

によってパーティションとしてそれを作ることができます。..あなたはすべての列がGROUP BY句になければなりませんSELECT文の方すべての列に言及していることを回避するために ..

SELECT * 
    FROM order_details 
    GROUP BY order_no,order_details,etc 

など、それはORDER_DETAILSテーブルからすべての列を意味します。