ふりかえり

本記事からは、SQLの基本、実務使用例編に入ります。
SQLの基礎に関しましては、
【初学者必見!】SQLの超基礎編の記事をご覧くださいませ。

本編に入ります!
副問い合わせの基本構文

まずは、基本構文から見ていきましょう!
select 列名1, 列名2, ...
from テーブル名
where 列名 = (select 列名 from 他のテーブル where 条件);

whereの中に、さらにselectがあるよ!

はい、そうです!
副問い合わせ(サブクエリ) とは、SELECT 文の中に別の SELECT 文を埋め込むことで、他のクエリの結果を利用してデータを取得する方法です。
副問い合わせは、次のような場面で活用されます。
ある条件を満たすデータのみを取得する
最大値・最小値・平均値などの集計結果を利用する
特定の条件を持つデータが存在するかをチェックする
max() 関数の基本構文

まずは、基本構文から見ていきましょう!
select max(列名) from テーブル名 where 条件;

まっくすって何だろう?

max() は、指定した列の最大値を取得する集計関数です!
実務では、最新のデータを取ってきたいときに、よく使用されています。
実務レベルの使用例を見ていこう!

実際に、SQLを使用してデータを確認していきましょう。
SQLに関しては以下を使用して解説していきます。
create table文、select文、insert文、update文、delete文、
drop table文、につきましては、過去にアップロードした
【初学者必見!】SQLの超基礎編の記事をご覧くださいませ。

目次の、「ふりかえり」のところにそれぞれの記事のリンクが
貼ってあるよ!
または、サイドバーのカテゴリーにSQLがあるから、そちらからでも
参照できます!
[事前準備]今回、実行するSQLの一覧
-- 申請管理情報テーブルの作成
create table 申請管理情報 (
STAFF_NO varchar2(10) not null, -- 職員番号 (Staff Number)
APPLI_NO varchar2(10) not null, -- 申請番号 (Application Number)
APPLI_DATE date, -- 申請年月日 (Application Date)
APPROVAL_DATE date, -- 承認日 (Approval Date)
SEND_BACK_DATE date, -- 差戻年月日 (Send Back Date)
APPLICATION_CONTENT varchar2(50), -- 申請内容 (Application Content)
constraint PK_申請管理情報 primary key (STAFF_NO, APPLI_NO)
);
create table 申請内容の詳細 (
職員番号 varchar2(10) not null, -- 親テーブルの STAFF_NO に対応
申請番号 varchar2(10) not null, -- 親テーブルの APPLI_NO に対応
申請内容の詳細 varchar2(100), -- 申請の詳細内容を格納するカラム
constraint PK_申請内容の詳細 primary key (職員番号, 申請番号),
constraint FK_申請内容の詳細 foreign key (職員番号, 申請番号)
references 申請管理情報 (STAFF_NO, APPLI_NO)
);
insert into 申請管理情報 (STAFF_NO, APPLI_NO, APPLI_DATE)
values ('1001', 'A001', TO_DATE('2024-02-25', 'YYYY-MM-DD'));
insert into 申請管理情報 (STAFF_NO, APPLI_NO, APPLI_DATE)
values ('1001', 'A002', TO_DATE('2024-02-26', 'YYYY-MM-DD'));
insert into 申請管理情報 (STAFF_NO, APPLI_NO, APPLI_DATE)
values ('1001', 'A003', TO_DATE('2024-02-27', 'YYYY-MM-DD'));
insert into 申請管理情報 (STAFF_NO, APPLI_NO, APPLI_DATE)
values ('1001', 'a003', TO_DATE('2024-01-27', 'YYYY-MM-DD'));
insert into 申請管理情報 (STAFF_NO, APPLI_NO, APPLI_DATE)
values ('1001', 'A004', TO_DATE('2024-02-28', 'YYYY-MM-DD'));
insert into 申請内容の詳細 (職員番号, 申請番号, 申請内容の詳細)
values ('1001', 'A001', 'レギュラーとハイオク間違えたので、もう一回入れに行きたいです。');
insert into 申請内容の詳細 (職員番号, 申請番号, 申請内容の詳細)
values ('1001', 'A002', 'ガソリン高いから、もっと補助してほしい');
insert into 申請内容の詳細 (職員番号, 申請番号, 申請内容の詳細)
values ('1001', 'A003', 'ハイオク満タンにしちゃった');
insert into 申請内容の詳細 (職員番号, 申請番号, 申請内容の詳細)
values ('1001', 'a003', 'レギュラー満タンにしちゃった');
各職員の最新の申請日を取得する
各 STAFF_NO(職員番号)について、最新の APPLI_DATE(申請年月日)を取得する方法です。
select STAFF_NO, max(APPLI_DATE) as 最新申請日
from 申請管理情報
group by STAFF_NO;

max(APPLI_DATE) を使うことで、STAFF_NO ごとに最も新しい申請日を取得します。
group by STAFF_NO によって、職員ごとにデータをまとめます。
申請管理情報 の STAFF_NO 列に対して max() を適用することで、最新の APPLI_DATE が得られます。
最新の申請内容を取得する
各 STAFF_NO ごとに最新の申請内容 (APPLICATION_CONTENT) を取得する方法です。
select STAFF_NO, APPLI_NO, APPLI_DATE
from 申請管理情報
where APPLI_DATE = (select max(APPLI_DATE) from 申請管理情報);

サブクエリ(副問い合わせ)(select max(APPLI_DATE) from 申請管理情報)
→ すべての申請の中から最大(最新)の APPLI_DATE を取得。メインクエリwhere APPLI_DATE = (サブクエリの結果)
→ APPLI_DATE が最新の日付のレコードだけを取得。
申請回数が最も多い職員を取得する
最も多く申請を行った職員 (STAFF_NO) を特定します。
select STAFF_NO, count(*) as 申請回数
from 申請管理情報
group by STAFF_NO
having count(*) = (
select max(申請回数)
from (
select count(*) as 申請回数
from 申請管理情報
group by STAFF_NO
)
);

まず、各職員の申請回数をカウント
group by STAFF_NOで職員ごとにグループ化。count(*)で申請件数を集計。
サブクエリで最大の申請回数を取得
select max(申請回数)により、最も申請回数の多い職員の申請件数を特定。
having で最も多い申請回数を持つ職員のみを抽出
having count(*) = (副問い合わせ)により、最大の申請回数を持つ職員だけを取得。
申請回数が3回以上の職員のうち、最新の申請を取得する
select STAFF_NO, APPLI_NO, APPLI_DATE
from 申請管理情報
where STAFF_NO in (
select STAFF_NO
from 申請管理情報
group by STAFF_NO
having count(*) >= 3
)
and APPLI_DATE = (
select max(APPLI_DATE)
from 申請管理情報 sm2
where sm2.STAFF_NO = 申請管理情報.STAFF_NO
);

STAFF_NO ごとの申請回数が3回以上 の職員を特定(サブクエリ)。
その職員の 最新の申請 (max(APPLI_DATE)) のみを取得。
STAFF_NO in (サブクエリ) によって、申請が3回以上ある職員だけに限定。
まとめ

副問い合わせとmax関数について解説しました。
次回もお楽しみに!










コメント