web-dev-qa-db-ja.com

GROUP BYとORDER BYの組み合わせ

GROUP BY句は行をグループ化しますが、結果を特定の順序でソートする必要はありません。順序を変更するには、GROUP BY句の後にあるORDER BY句を使用します。 ORDER BY句で使用される列は、SELECTリストに表示される必要があります。これは、ORDER BYの通常の使用とは異なります。 [例によるOracle、第4版、274ページ]

何故ですか? GROUP BYを使用すると、SELECT句で必要な列が影響を受けるのはなぜですか。

また、GROUP BYを使用しない場合:なぜ一部の列をORDER BYしたいのに、列のサブセットのみを選択するのですか?

9
fredoverflow

実際、Dave Costaの例が示すように、ステートメントは完全に真ではありません

Oracleのドキュメントには、式を使用できると記載されていますが、式は選択リストの列に基づいている必要があります。

expr-exprは、exprの値に基づいて行を並べ替えます。式は、選択リストの列、またはFROM句のテーブル、ビュー、またはマテリアライズドビューの列に基づいています。出典:Oracle®Database SQL言語リファレンス11gリリース2(11.2)E26088-01 2011年9月。

同じ作品から19-13および19-33ページ(PDFの1355ページと1365ページ)

enter image description here

enter image description here

http://docs.Oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#SQLRF01702

http://docs.Oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#i2171079

5
hol

引用からの太字のテキストは正しくありません(多くの一般的な使用例ではtrueにすぎますが、要件として厳密には当てはまりません)。たとえば、AVG(val)が選択リストにない場合でも、次のステートメントは問題なく実行されます。

WITH DATA AS (SELECT mod(LEVEL,3) grp, LEVEL val FROM dual CONNECT BY LEVEL < 100)
SELECT grp,MIN(val),MAX(val)
FROM DATA
GROUP BY grp
ORDER BY AVG(val)

ORDER BY句の式は、GROUP BYのコンテキストで評価できる必要があります。たとえば、上記の例ではORDER BY valは機能しません。これは、式valに、グループ化によって生成された各行に対する個別の値がないためです。

2番目の質問については、順序付けに関心があるかもしれませんが、順序付け式の値には関心がありません。選択リストから不要な式を除外すると、サーバーからクライアントに実際に送信する必要があるデータの量が減ります。

6
Dave Costa

最初:

Group byの実装は、元のfrom句(テーブルビューまたは一部の結合テーブル)とは構造が異なる新しい結果セットを作成するものです。その結果セットは、何を選択するかによって定義されます。

すべてのSQL RDBMSにこの制限があるわけではありませんが、グループ化されていない列(AVGSUMなど)の集計関数か、これはグループ化操作の結果の論理的な要件であるため、グループ化された列、またはそれらの結果の2つ以上に基づいて機能する(2つの列の追加など)。

第二:

あなたは注文のためにその列だけを気にするからです。たとえば、売上を上げずに売れ行きの良いシングルのリストがある場合があります(NYTベストセラーはデータの詳細の一部を秘密にしていますが、ランク付けされたリストがあります)。もちろん、その列を選択して使用しないことで、これを回避できます。

3
Jon Hanna

サンプル表

sample.grades
Name   Grade    Score
Adam   A        95
Bob    A        97
Charlie C       75

GROUP BYを使用した最初のクエリ

Select grade, count(Grade) from sample.grades GROUP BY Grade

出力

Grade Count
A     2
C     1

Order byを使用した2番目のクエリ

select Name, score from sample grades order by score

出力

Bob    A        97
Adam   A        95
Charlie C       75

GROUP BYと順序付けを使用した3番目のクエリ

Select grade, count(Grade) from sample.grades GROUP BY Grade desc

出力

Grade Count
A     2
C     1

カウントなどを使い始めたら、グループ化する必要があります。一緒に使用することもできますが、使用例が明確に示されているように、用途は大きく異なります。

質問に答えるために、なぜselectセクションのアイテムをグループ化するのですか?列ごとにグループ化しないと、列のカウントを実行できません。

2番目の質問、なぜすべての列を並べ替えるのではなく、並べ替えたいのですか?スコアで注文したいのですが、実際の成績やスコアも気にしない場合

select name from sample.grades order by score

出力

Name
Bob
Adam
Charlie

データは、ORDER BYでソートされる前に集計されます。

他の列(group byリストまたは集計関数にない)で並べ替えようとすると、どの値が使用されますか?順序付けに使用する単一の値はありません。

並べ替えには値の組み合わせを使用できると思います。だからあなたは言うことができます:

order by a+b

Aとbがグループ化されている場合。 SELECTで言及されていない列を導入することはできません。ただし、SELECTに記載されていない集計関数を使用できると思います。

2
Gordon Linoff

選択リストにリストされておらず、group by句に含まれていない列による順序付けがどの結果になると思いますか?いずれにせよ、SELECTリストの列で言及されていない並べ替えはすべて省略されるため、Oracleの担当者は制限を正しく追加しました。

with c as (
select 1 id, 2 value from dual
union all
select 1 id, 3 value from dual
union all
select 2 id, 3 value from dual
)
select id
from c
group by id
order by count(*) desc
0

ここで私の理解

「GROUP BY句は行をグループ化しますが、必ずしも特定の順序で結果をソートするわけではありません。」

->あなたは注文なしでGroup byを使うことができます

「順序を変更するには、GROUP BY句の後にあるORDER BY句を使用します。」

->行は主キーでデフォルトで選択されます。順序を追加する場合は、グループ化後に追加する必要があります

「ORDER BY句で使用される列は、通常のORDER BYの使用とは異なり、SELECTリストに表示される必要があります。」

0
Aghilas Yakoub