データベースで実行する必要がある 2 つの "IN" ステートメントを使用するかなり恐ろしいクエリがあります。まず、スキーマ (この例では単純化されています):
CREATE TABLE [dbo].[SystemUser]
(
[SystemUserID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](50) NULL,
[Surname] [nvarchar](50) NULL
CONSTRAINT [PK_ApplicationUser] PRIMARY KEY CLUSTERED
(
[SystemUserID] ASC
)
)
GO
CREATE TABLE [dbo].[Group]
(
[GroupID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NULL
CONSTRAINT [PK_Group] PRIMARY KEY CLUSTERED
(
[GroupID] ASC
)
)
GO
CREATE TABLE [dbo].[GroupMembership]
(
[SystemUserID] [int] NOT NULL,
[GroupID] [int] NOT NULL
CONSTRAINT [PK_GroupMembership] PRIMARY KEY CLUSTERED
(
[SystemUserID] ASC,
[GroupID] ASC
)
)
GO
私がしたいのは、GroupID のリストにある「グループ」へのメンバーシップを持たない SystemUserID のリストに一致するすべての「SystemUser」レコードを見つけることです。
そのため、ID の 2 つの個別のリストが 1 つのクエリで比較されます。現在これを行うと考えられる最速の方法は次のとおりです。
SELECT SU.SystemUserID
FROM [dbo].[SystemUser] SU
LEFT JOIN
(
SELECT GM.SystemUserID
FROM [dbo].[GroupMembership] GM
WHERE GM.GroupID IN
(
1, 7, 8, 10, 32
)
) GM ON GM.SystemUserID = SU.SystemUserID
WHERE SU.SystemUserID IN
(
10, 61, 80, 93, 98
)
AND GM.SystemUserID IS NULL /* Not matched */
足りないものはありますか; 「WHERE NOT EXISTS」チェックはより効率的でしょうか? または、2 つのリストによる処理とフィルタリングのより良い方法を考えられますか?