特定のカラムで重複を排除し、重複排除に利用したカラム以外の列も取得するクエリ
タイトルのようなことが出来るか?と聞かれて、即答できなかったので備忘録として記事にしました。
下記のようなテーブルがあったとする。
社員情報テーブル(Staff)
| StaffId | Name | Department | JoinYear |
|---|---|---|---|
| 001 | ディアボロ | 取締 | 1986 |
| 018 | ブローノ・ブチャラティ | 護衛 | 1997 |
| 019 | パンナコッタ・フーゴ | 護衛 | 1998 |
| 022 | ナランチャ・ギルガ | 護衛 | 1999 |
| 024 | レオーネ・アバッキオ | 護衛 | 2000 |
| 025 | グイード・ミスタ | 護衛 | 2000 |
| 026 | ジョルノ・ジョバーナ | 護衛 | 2001 |
| 003 | リゾット・ネエロ | 暗殺 | 1990 |
| 020 | ホルマジオ | 暗殺 | 1998 |
| 010 | イルーゾォ | 暗殺 | 1995 |
| 005 | プロシュート | 暗殺 | 1992 |
| 023 | ペッシ | 暗殺 | 1999 |
| 011 | メローネ | 暗殺 | 1995 |
| 015 | ギアッチョ | 暗殺 | 1996 |
| 008 | ソルベ | 暗殺 | 1994 |
| 009 | ジェラート | 暗殺 | 1994 |
| 012 | スクアーロ | 親衛隊 | 1995 |
| 013 | ティッツァーノ | 親衛隊 | 1995 |
| 016 | カルネ | 親衛隊 | 1996 |
| 006 | チョコラータ | 親衛隊 | 1993 |
| 007 | セッコ | 親衛隊 | 1993 |
| 021 | ルカ | その他 | 1998 |
| 017 | マリオ・ズッケェロ | その他 | 1996 |
| 014 | サーレー | その他 | 1995 |
| 004 | ポルポ | その他 | 1991 |
| 002 | ペリーコロ | その他 | 1988 |
| ※入社年度は適当。 |
このテーブルから所属部門で重複を排除して、入社年度の早い人のデータを取得したい。
期待する結果
| StaffId | Name | Department | JoinYear |
|---|---|---|---|
| 001 | ディアボロ | 取締 | 1986 |
| 018 | ブローノ・ブチャラティ | 護衛 | 1997 |
| 003 | リゾット・ネエロ | 暗殺 | 1990 |
| 006 | チョコラータ | 親衛隊 | 1993 |
| 002 | ペリーコロ | その他 | 1988 |
distinctでサクッと上手くいくかと思ったが、distinctをかける以外のカラムも取得したいということで悩んでしまった。
質問をした人の環境はMySqlだったので distinct on を使用することで解決したが、
自環境がSQLServerでdistinct onはなくちょっとググっても該当するようなものがなかったので、
どうすれば良いかに考えてみたら、以下で出来た。
実際のクエリ
select.sql
select tempStaff.StaffId
,tempStaff.Name
,tempStaff.Department
,tempStaff.JoinYear
from (select rank() over(partition by Department order by JoinYear) as rk
,*
from dbo.Staff) as tempStaff
where tempStaff.rk = 1
order by tempStaff.Department
特定のカラムで重複を排除したい という言葉でDistinctをどう使えばいいのかと悩んでしまったが、
集計関数を使用してグループ毎に順番を決めて先頭を取得すれば出来た。
もっと簡単なやり方を知っている方がいればご教示ください。
同じように困る人がいるかもしれないので、このタイトルにしておきます。