🦕
[SQL Server】差集合を取得する
※備忘録用
ログインしたユーザーは複数のユーザーグループに所属できる。
ユーザーグループによって表示されるプロモーションがあり、今回はログインしたユーザーには表示してはいけないプロモーション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