Microsoft SQL Server
GROUP BY
サーチ…
単純なグループ化
注文表
顧客ID | 製品番号 | 量 | 価格 |
---|---|---|---|
1 | 2 | 5 | 100 |
1 | 3 | 2 | 200 |
1 | 4 | 1 | 500 |
2 | 1 | 4 | 50 |
3 | 5 | 6 | 700 |
特定の列でグループ化する場合、この列の一意の値のみが返されます。
SELECT customerId
FROM orders
GROUP BY customerId;
戻り値:
顧客ID |
---|
1 |
2 |
3 |
count()
ような集計関数は、完全なテーブルではなく、各グループに適用されます。
SELECT customerId,
COUNT(productId) as numberOfProducts,
sum(price) as totalPrice
FROM orders
GROUP BY customerId;
戻り値:
顧客ID | numberOfProducts | 合計金額 |
---|---|---|
1 | 3 | 800 |
2 | 1 | 50 |
3 | 1 | 700 |
複数の列によるGROUP
1つは複数の列をGROUP BYすることができます
declare @temp table(age int, name varchar(15))
insert into @temp
select 18, 'matt' union all
select 21, 'matt' union all
select 21, 'matt' union all
select 18, 'luke' union all
select 18, 'luke' union all
select 21, 'luke' union all
select 18, 'luke' union all
select 21, 'luke'
SELECT Age, Name, count(1) count
FROM @temp
GROUP BY Age, Name
年齢と名前の両方でグループ化し、次を生成します:
年齢 | 名 | カウント |
---|---|---|
18 | ルーク | 3 |
21 | ルーク | 2 |
18 | マット | 1 |
21 | マット | 2 |
複数のテーブル、複数の列でグループ化する
group byは、joinステートメントでよく使用されます。 2つのテーブルがあるとしましょう。最初のものは学生のテーブルです:
イド | フルネーム | 年齢 |
---|---|---|
1 | マットジョーンズ | 20 |
2 | フランクブルー | 21 |
3 | アンソニーエンジェル | 18 |
2番目の表は、各生徒が受けることができる科目の表です:
Subject_Id | 件名 |
---|---|
1 | 数学 |
2 | PE |
3 | 物理 |
そして、1人の学生が多くの科目に出席できるので、1つの科目には多くの学生が出席することができます(N:N関係)ので、3番目の「境界」表が必要です。テーブルStudents_subjectsを呼び出してみましょう:
Subject_Id | 学生証 |
---|---|
1 | 1 |
2 | 2 |
2 | 1 |
3 | 2 |
1 | 3 |
1 | 1 |
さて、それぞれの学生が出席している科目の数を知りたいとしましょう。ここでは、スタンドアロンのGROUP BY
ステートメントでは、単一のテーブルから情報を取得できないため、十分ではありません。したがって、 JOIN
文でGROUP BY
を使用する必要があります。
Select Students.FullName, COUNT(Subject Id) as SubjectNumber FROM Students_Subjects
LEFT JOIN Students
ON Students_Subjects.Student_id = Students.Id
GROUP BY Students.FullName
指定されたクエリの結果は次のとおりです。
フルネーム | SubjectNumber |
---|---|
マットジョーンズ | 3 |
フランクブルー | 2 |
アンソニーエンジェル | 1 |
GROUP BYのさらに複雑な使用例については、studentsが同じ名前を複数回割り当てることができるとします(Students_Subjectsの表を参照)。このシナリオでは、複数の列でGROUPすることで、各科目が学生に割り当てられた回数を数えることができます。
SELECT Students.FullName, Subjects.Subject,
COUNT(Students_subjects.Subject_id) AS NumberOfOrders
FROM ((Students_Subjects
INNER JOIN Students
ON Students_Subjcets.Student_id=Students.Id)
INNER JOIN Subjects
ON Students_Subjects.Subject_id=Subjects.Subject_id)
GROUP BY Fullname,Subject
このクエリの結果は次のとおりです。
フルネーム | 件名 | SubjectNumber |
---|---|---|
マットジョーンズ | 数学 | 2 |
マットジョーンズ | PE | 1 |
フランクブルー | PE | 1 |
フランクブルー | 物理 | 1 |
アンソニーエンジェル | 数学 | 1 |
HAVING
そのためWHERE
句が前に評価されたGROUP BY
、あなたが使用することはできませんWHERE
グループ(のような通常の集約関数の結果ダウン削り取っするCOUNT(*)
)。この必要性を満たすために、 HAVING
節を使用することができます。
たとえば、次のデータを使用します。
DECLARE @orders TABLE(OrderID INT, Name NVARCHAR(100))
INSERT INTO @orders VALUES
( 1, 'Matt' ),
( 2, 'John' ),
( 3, 'Matt' ),
( 4, 'Luke' ),
( 5, 'John' ),
( 6, 'Luke' ),
( 7, 'John' ),
( 8, 'John' ),
( 9, 'Luke' ),
( 10, 'John' ),
( 11, 'Luke' )
一人一人が注文した注文数を取得したい場合は、
SELECT Name, COUNT(*) AS 'Orders'
FROM @orders
GROUP BY Name
そして
名 | 注文 |
---|---|
マット | 2 |
ジョン | 5 |
ルーク | 4 |
ただし、これを2つ以上の注文を行った個人に限定したい場合は、 HAVING
節を追加することができます。
SELECT Name, COUNT(*) AS 'Orders'
FROM @orders
GROUP BY Name
HAVING COUNT(*) > 2
収穫する
名 | 注文 |
---|---|
ジョン | 5 |
ルーク | 4 |
GROUP BY
と同様に、 HAVING
置かれたカラムは、 SELECT
文の対応するカラムと正確に一致しなければならないことに注意してください。上記の例では、代わりに
SELECT Name, COUNT(DISTINCT OrderID)
私たちのHAVING
句は
HAVING COUNT(DISTINCT OrderID) > 2
ROLLUPとCUBEを使用したGROUP BY
ROLLUP演算子は小計と合計を含むレポートを生成するのに便利です。
CUBEは、選択した列の値のすべての組み合わせの集計を示す結果セットを生成します。
ROLLUPは、選択した列の値の階層の集計を示す結果セットを生成します。
項目 色 量 表 青 124 表 赤 223 椅子 青 101 椅子 赤 210
SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
ELSE ISNULL(Item, 'UNKNOWN')
END AS Item,
CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
ELSE ISNULL(Color, 'UNKNOWN')
END AS Color,
SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH ROLLUP
Item Color QtySum
-------------------- -------------------- --------------------------
Chair Blue 101.00
Chair Red 210.00
Chair ALL 311.00
Table Blue 124.00
Table Red 223.00
Table ALL 347.00
ALL ALL 658.00
(7行影響を受ける)
問合せのROLLUPキーワードがCUBEに変更された場合、CUBE結果セットは同じですが、最後に2つの追加行が戻されます。
ALL Blue 225.00
ALL Red 433.00
https://technet.microsoft.com/en-us/library/ms189305(v=sql.90).aspx