【SQL Server】GROUP BY 句・HAVING 句 の使い方

SQL Server
この記事は約5分で読めます。

概要

GROUP BY 句 は レコードをグループ化することが出来ます。
HAVING 句 は グループ化したレコードに対して条件を指定出来ます。

グループ化というのは、例えば、学校でテスト結果を集計したテーブルがあったとします。これを学年別にグループ化して、平均値を求めたり、男女別にグループ化して、最高点数を求めるような場合に使用します。

グループ化したレコードに対して条件というのは、例えば、全教科のテストの平均点が30点以下のレコードを求めるような場合に使用します。

また、GROUP BY 句 と HAVING 句 は大抵の場合一緒に使われますが、必ずしも一緒に使う必要はありません。

内容

事前準備としてデータを用意します。

CREATE TABLE [dbo].[T1](
	[ID] INT  ,
	[名前] NVARCHAR(30) ,
	[誕生年] INT ,
	[生没年] INT ,
	[年号] NVARCHAR(10) ,
	[性別] CHAR(2) ,
)


INSERT INTO T1([ID],[名前],[誕生年],[生没年],[年号],[性別]) VALUES
(1,'芥川龍之介',1892 ,1927,'明治','男'),
(2,'阿部公房',1924 ,1993,'大正','男'),
(3,'有島武郎',1878 ,1923,'明治','男'),
(4,'江戸川乱歩',1894 ,1965,'明治','男'),
(5,'川端康成',1899  ,1972,'明治','男'),
(6,'菊池寛',1888 ,1948,'明治','男'),
(7,'司馬遼太',1923  ,1996,'大正','男'),
(8,'太宰治',1909  ,1948,'明治','男'),
(9,'樋口一葉',1872  ,1896,'明治','女'),
(10,'与謝野 晶子',1878  ,1942,'明治','女'),
(11,'向田 邦子',1929  ,1981,'昭和','女'),
(12,'筒井 康隆',1934  ,null,'昭和','男')

SELECT * FROM T1
ID 名前 誕生年 生没年 年号 性別
1 芥川龍之介 1892 1927 明治
2 阿部公房 1924 1993 大正
3 有島武郎 1878 1923 明治
4 江戸川乱歩 1894 1965 明治
5 川端康成 1899 1972 明治
6 菊池寛 1888 1948 明治
7 司馬遼太 1923 1996 大正
8 太宰治 1909 1948 明治
9 樋口一葉 1872 1896 明治
10 与謝野 晶子 1878 1942 明治
11 向田 邦子 1929 1981 昭和
12 筒井 康隆 1934 NULL 昭和

 

誕生年が一番最近の年を男女別に取得する

SELECT MAX([誕生年]) AS 誕生年 FROM T1
誕生年
1934

これだと全レコードの中からの最近の年なので、GROUP BY 句 を使用して男女別に集計します。

SELECT [性別],MAX([誕生年]) AS 誕生年 FROM T1
GROUP BY [性別]
性別 誕生年
1929
1934

GROUP BY 句で指定した区分毎にまとめてからそれぞれのMAX値をとります。

もっと単純に性別が何種類あるかを確認します。

SELECT [性別] FROM T1
GROUP BY [性別]
性別

性別でまとめているのがわかります。これに集計関数のMAX を使って男女別に最高値を取得しています。GROUP BY 句 を使ったからと言って必ず、集計関数を使う必要はありません。

もっと、細かくグループ化することも出来ます。

男女別、年号別に誕生年が一番若い年を取得する

GROUP BY 句に 指定するカラムを2つにします。

SELECT [性別],[年号],MAX([誕生年]) AS 誕生年 FROM T1
GROUP BY [性別],[年号]
性別 年号 誕生年
昭和 1929
昭和 1934
大正 1924
明治 1878
明治 1909

より細かくグループ化出来ています。また、大正生まれの女性はいないのでレコードとしては出力されませんでした。

HAVING 句 の使い方

HAVING 句 は グループ化または、集計関数の結果に対して条件を指定出来ます。

WHERE 句 のように使うとエラーになります。

SELECT * FROM T1
HAVING [年号] = '昭和'
メッセージ 8121、レベル 16、状態 1、行 32
列 'T1.年号' は HAVING 句内では無効です。この列は集計関数または GROUP BY 句に含まれていません。

作家が2人以下の年号を求めるには下記のように年号別にグループ化してからHAVING 句 で条件を指定します。

SELECT [年号],COUNT(*) AS 人数 FROM T1
GROUP BY [年号]
HAVING COUNT([年号]) <= 2
年号 人数
昭和 2
大正 2

 

HAVING 句はGROUP BY 句 とセットで使わなくてもいい

ほとんどの場合、HAVING 句は、GROUP BY 句 とセットで使います。使う場面は少ないでしょうが、一応セットで使わなくても構文としては、成立します。

SELECT 1 FROM T1
HAVING COUNT([年号]) = 12

コメント

タイトルとURLをコピーしました