web-dev-qa-db-ja.com

集約関数なしのGROUP BY

GROUP BY (Oracle dbmsの新機能)集約関数なしで理解しようとしています。
どのように動作しますか?
これが私が試したことです。

SQLを実行するEMPテーブル。
EMP TABLE

SELECT ename , sal
FROM emp
GROUP BY ename , sal

Result

SELECT ename , sal  
FROM emp  
GROUP BY ename;  

結果

ORA-00979:GROUP BY式ではありません
00979。 00000-「GROUP BY式ではありません」
*原因:
*アクション:
エラー:行:397列:16

SELECT ename , sal  
FROM emp  
GROUP BY sal;  

結果

ORA-00979:GROUP BY式ではありません
00979。 00000-「GROUP BY式ではありません」
*原因:
*アクション:行のエラー:411列:8

SELECT empno , ename , sal  
FROM emp  
GROUP BY sal , ename;  

結果

ORA-00979:GROUP BY式ではありません
00979。 00000-「GROUP BY式ではありません」
*原因:
*アクション:行のエラー:425列:8

SELECT empno , ename , sal  
FROM emp  
GROUP BY empno , ename , sal;  

Result

そのため、基本的に列の数はGROUP BY句の列の数と等しくなければなりませんが、それでも何が起こっているのか、何が起こっているのかまだわかりません。

59
XForCE07

これがGROUP BYの仕組みです。それはいくつかの行を取り、それらを1行に変えます。このため、一部の列(フィールド)に異なる値がある場合、結合されたすべての行をどうするかを知る必要があります。これが、選択するすべてのフィールドに2つのオプションがある理由です。GROUPBY句に含めるか、集計関数で使用して、フィールドの結合方法をシステムに認識させます。

たとえば、次の表があるとします。

Name | OrderNumber
------------------
John | 1
John | 2

GROUP BY Nameと言うと、どのOrderNumberが結果に表示されるかをどのように知るのでしょうか?そのため、GroupByにOrderNumberを含めると、これら2つの行が生成されます。または、集計関数を使用して、OrderNumbersの処理方法を示します。たとえば、結果がJohn | 2であることを意味するMAX(OrderNumber)または結果がJohn | 3であることを意味するSUM(OrderNumber)です。

87
Tobberoth

このデータが与えられた場合:

Col1  Col2  Col3
 A     X     1
 A     Y     2
 A     Y     3
 B     X     0
 B     Y     3
 B     Z     1

このクエリ

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2, Col3

結果はまったく同じテーブルになります。

ただし、このクエリ:

SELECT Col1, Col2 FROM data GROUP BY Col1, Col2

結果として

Col1  Col2
 A     X  
 A     Y  
 B     X  
 B     Y  
 B     Z  

次に、クエリ:

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2

問題が発生します:A、Yの行は、2行をグループ化した結果です

 A     Y     2
 A     Y     3

それで、Col3、 '2'、または '3'にはどの値が必要ですか?

通常、group byを使用して計算します。合計:

SELECT Col1, Col2, SUM(Col3) FROM data GROUP BY Col1, Col2

したがって、行に問題があり、(2 + 3)= 5になります。

選択内のすべての列でグループ化することは、DISTINCTを使用することと実質的に同じであり、この場合はDISTINCTキーワードのWord可読性を使用することをお勧めします。

代わりに

SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2, Col3

つかいます

SELECT DINSTINCT Col1, Col2, Col3 FROM data
28
oerkelens

GROUP BY句のstrict要件が発生しています。 group-by句にないすべての列には、一致する「グループ」のすべてのレコードを単一のレコード(sum、max、minなど)に減らすための関数を適用する必要があります。

GROUP BY句でクエリ(選択)されたすべての列をリストする場合、基本的には重複レコードを結果セットから除外するように要求しています。これは、結果セットから重複行を削除するSELECT DISTINCTと同じ効果をもたらします。

22
Mister_Tom

集約なしのGROUP BYの唯一の実際の使用例は、選択した列よりも多くの列をGROUP BYする場合です。この場合、選択した列が繰り返される可能性があります。そうでなければ、DISTINCTを使用することもできます。

他のRDBMSでは、すべての非集計列をGROUP BYに含める必要がないことに注意してください。たとえば、PostgreSQLでは、テーブルの主キー列がGROUP BYに含まれている場合、そのテーブルの他の列は、すべての個別の主キー列で異なることが保証されるため、必要はありません。過去に、多くの場合、OracleがよりコンパクトなSQLを作成するのと同じことをしたいと思っていました。

7
David Aldridge

いくつか例を挙げましょう。

このデータを考慮してください。

CREATE TABLE DATASET ( VAL1 CHAR ( 1 CHAR ),
                   VAL2 VARCHAR2 ( 10 CHAR ),
                   VAL3 NUMBER );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'b', 'b-details', 2 );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'a', 'a-details', 1 );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'c', 'c-details', 3 );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'a', 'dup', 4 );

INSERT INTO
      DATASET ( VAL1, VAL2, VAL3 )
VALUES
      ( 'c', 'c-details', 5 );

COMMIT;

今テーブルにあるもの

SELECT * FROM DATASET;

VAL1 VAL2             VAL3
---- ---------- ----------
b    b-details           2
a    a-details           1
c    c-details           3
a    dup                 4
c    c-details           5

5 rows selected.

-グループごとに集計

SELECT
      VAL1,
      COUNT ( * )
FROM
      DATASET A
GROUP BY
      VAL1;

VAL1   COUNT(*)
---- ----------
b             1
a             2
c             2

3 rows selected.

-複数の列でグループ化して集計するが、列の一部を選択する

SELECT
      VAL1,
      COUNT ( * )
FROM
      DATASET A
GROUP BY
      VAL1,
      VAL2;

VAL1  
---- 
b             
c             
a             
a             

4 rows selected.

-複数の列によるグループの集約なし

SELECT
      VAL1,
      VAL2
FROM
      DATASET A
GROUP BY
      VAL1,
      VAL2;

    VAL1  
    ---- 
    b    b-details
    c    c-details
    a    dup
    a    a-details

    4 rows selected.

-複数の列によるグループの集約なし

SELECT
      VAL1
FROM
      DATASET A
GROUP BY
      VAL1,
      VAL2;

    VAL1  
    ---- 
    b
    c
    a
    a

    4 rows selected.

選択にN列(集計を除く)がある場合、N列またはN + x列が必要です

4
SriniV

SELECT句に列がある場合、複数の行がある場合にどのように選択しますか?はい、SELECT句のすべての列はGROUP BY句にも含まれている必要があります。SELECT...

sELECT句ではないGROUP BY句に列を含めることができますが、そうでない場合はできません

3
ogres

サブクエリを使用:例:

SELECT field1,field2,(SELECT distinct field3 FROM tbl2 WHERE criteria) AS field3
FROM tbl1 GROUP BY field1,field2

OR

SELECT DISTINCT field1,field2,(SELECT distinct field3 FROM tbl2 WHERE criteria) AS field3
FROM tbl1
2

追加として

基本的に、列の数はGROUP BY句の列の数と等しくなければなりません

正しい文ではありません。

  • GROUP BY句の一部ではない属性は選択に使用できません
  • GROUP BY句の一部である属性は選択に使用できますが、必須ではありません。
1
sancz

次のようなデータがある場合は、group byを理解する必要があると言っていました。

COL-A  COL-B  COL-C  COL-D
  1      Ac      C1     D1
  2      Bd      C2     D2
  3      Ba      C1     D3
  4      Ab      C1     D4
  5      C       C2     D5

そして、あなたはデータを次のように見せたいです:

COL-A  COL-B  COL-C  COL-D
  4      Ab      C1     D4
  1      Ac      C1     D1
  3      Ba      C1     D3
  2      Bd      C2     D2
  5      C       C2     D5

あなたが使う:

select * from table_name
order by col-c,colb

これはあなたがやろうとしていることだと思うからです。

0
user2839702