🦕

[SQL Server】差集合を取得する

2023/02/19に公開

※備忘録用

ログインしたユーザーは複数のユーザーグループに所属できる。
ユーザーグループによって表示されるプロモーションがあり、今回はログインしたユーザーには表示してはいけないプロモーションIDを取得したかった。

IN句の否定形で取得できそうだったが、ユーザーグループは結構な頻度で追加や削除がされるため、今回は差集合(EXCEPT)で取得した。

DB

ユーザーグループTb

Id UserGroup
1 グループA
2 グループB
3 グループC

プロモーションTb

Id PromtionName
1 全UserGroupに表示するプロモーション
2 グループAにのみ表示するプロモーション
3 グループAにのみ表示するプロモーション
4 グループBにのみ表示するプロモーション
5 グループCにのみ表示するプロモーション

プロモーションユーザーグループTb

Id UserGroupId PromtionId
1 1 1
2 1 2
3 1 3
4 2 1
5 2 4
6 3 1
7 3 5

データの取得

SQL

SELECT DISTINCT PromotionId from PromotionsUserGroups where UserGroupId != @UserGroupId
EXCEPT
SELECT DISTINCT PromotionId from PromotionsUserGroups where UserGroupId =@UserGroupId

結果
ログインユーザーがGroupAだった場合

PromotionId
4
5

ログインユーザーがGroupBだった場合

PromotionId
2
3
5

ログインユーザーがGroupCだった場合

PromotionId
2
3
4

EXCEPTで差を抽出は複数テーブルを対象にできるが、カラム数は同じである必要があるため、実際のSQLではWITH句を利用して比較したいテーブルを先に作成した。

WITH tb1 AS (
 ),
 tb2 AS (
 ),
 tb3 AS (
 )
SELECT  PromotionId from tb1 
EXCEPT
SELECT  PromotionId from tb2
EXCEPT
SELECT  PromotionId from tb3

Discussion