SELECT 来自两个 table 的记录,其中行可能不存在于第二个 table 中(与 LEFT JOIN 相关)
SELECT records from two tables where rows might not present in the second table (related to LEFT JOIN)
我有两个 tables - Module 和 Access.
模块 - master table 有模块列表。
Access - 映射具有相应权限的用户和模块(如果用户对相应模块具有权限,HasAccess 的值将为 1如果用户没有权限,HasAccess 的值将为 0,否则该行将不存在)
要求 -
我需要一个包含特定用户各自权限的所有模块名称的列表。 (棘手的部分 - 根据 Access table 的结构,对于特定用户,所有模块都没有必要出现在映射 table 中,如所解释的以上)
请查看我的查询,它运行良好并且涵盖了所有场景。我想知道除此之外是否还有更好的方法,或者您是否发现我的方法有任何问题。
-- Table Module
IF (OBJECT_ID('tempdb..#Module') IS NOT NULL)
DROP TABLE #Module
CREATE TABLE #Module (
[ID] INT PRIMARY KEY
,[Name] VARCHAR(20)
)
INSERT #Module (
[ID]
,[Name]
)
VALUES (1, 'Module 1')
,(2, 'Module 2')
,(3, 'Module 3')
,(4, 'Module 4')
,(5, 'Module 5')
-- Table Access
IF (OBJECT_ID('tempdb..#Access') IS NOT NULL)
DROP TABLE #Access
CREATE TABLE #Access (
[ID] INT FOREIGN KEY REFERENCES #Module([ID])
,[UserName] VARCHAR(20)
,[HasAccess] BIT
)
INSERT #Access (
[ID]
,[UserName]
,[HasAccess]
)
VALUES (2, 'User 1', 1)
,(3, 'User 2', 1)
,(4, 'User 2', 0)
,(4, 'User 1', 0)
,(5, 'User 1', 1)
-- List of modules and respective access for 'User 1'
DECLARE @UserName VARCHAR(20) = 'User 1'
SELECT #Module.[Name] AS [Module]
,ISNULL(#Access.[HasAccess], 0) AS [Access]
FROM #Module
LEFT JOIN #Access ON #Access.[ID] = #Module.[ID]
AND #Access.[UserName] = @UserName
Table模块的内容-
Table 的内容 用户访问 - 'User 1'-
结果('User 1' 的模块列表和各自的访问权限)-
您可以使用 exists
作为子查询:
select m.*,
(case when exists (select 1
from #access a
where a.id = m.id and a.username = 'User 1' and
a.HasAccess = 1
)
then 1 else 0
end) as has_access
from #modules m;
@Amit11794,如果您希望特定用户的结果作为硬编码值或在变量中传递,您的方法是正确的。
但是,如果您希望一次查询所有用户的结果,您可以使用以下方法。
SELECT #Module.*,users.UserName, isnull(#Access.HasAccess ,0) as HasAccess
FROM #Module
cross join (select distinct Username from #Access) users
left join #Access on #Module.id = #Access.id and users.username = #Access.UserName
结果集
ID Name UserName HasAccess
----------- -------------------- -------------------- ---------
1 Module 1 User 1 0
2 Module 2 User 1 1
3 Module 3 User 1 0
4 Module 4 User 1 0
5 Module 5 User 1 1
1 Module 1 User 2 0
2 Module 2 User 2 0
3 Module 3 User 2 1
4 Module 4 User 2 0
5 Module 5 User 2 0
我有两个 tables - Module 和 Access.
模块 - master table 有模块列表。
Access - 映射具有相应权限的用户和模块(如果用户对相应模块具有权限,HasAccess 的值将为 1如果用户没有权限,HasAccess 的值将为 0,否则该行将不存在)
要求 - 我需要一个包含特定用户各自权限的所有模块名称的列表。 (棘手的部分 - 根据 Access table 的结构,对于特定用户,所有模块都没有必要出现在映射 table 中,如所解释的以上)
请查看我的查询,它运行良好并且涵盖了所有场景。我想知道除此之外是否还有更好的方法,或者您是否发现我的方法有任何问题。
-- Table Module
IF (OBJECT_ID('tempdb..#Module') IS NOT NULL)
DROP TABLE #Module
CREATE TABLE #Module (
[ID] INT PRIMARY KEY
,[Name] VARCHAR(20)
)
INSERT #Module (
[ID]
,[Name]
)
VALUES (1, 'Module 1')
,(2, 'Module 2')
,(3, 'Module 3')
,(4, 'Module 4')
,(5, 'Module 5')
-- Table Access
IF (OBJECT_ID('tempdb..#Access') IS NOT NULL)
DROP TABLE #Access
CREATE TABLE #Access (
[ID] INT FOREIGN KEY REFERENCES #Module([ID])
,[UserName] VARCHAR(20)
,[HasAccess] BIT
)
INSERT #Access (
[ID]
,[UserName]
,[HasAccess]
)
VALUES (2, 'User 1', 1)
,(3, 'User 2', 1)
,(4, 'User 2', 0)
,(4, 'User 1', 0)
,(5, 'User 1', 1)
-- List of modules and respective access for 'User 1'
DECLARE @UserName VARCHAR(20) = 'User 1'
SELECT #Module.[Name] AS [Module]
,ISNULL(#Access.[HasAccess], 0) AS [Access]
FROM #Module
LEFT JOIN #Access ON #Access.[ID] = #Module.[ID]
AND #Access.[UserName] = @UserName
Table模块的内容-
Table 的内容 用户访问 - 'User 1'-
结果('User 1' 的模块列表和各自的访问权限)-
您可以使用 exists
作为子查询:
select m.*,
(case when exists (select 1
from #access a
where a.id = m.id and a.username = 'User 1' and
a.HasAccess = 1
)
then 1 else 0
end) as has_access
from #modules m;
@Amit11794,如果您希望特定用户的结果作为硬编码值或在变量中传递,您的方法是正确的。
但是,如果您希望一次查询所有用户的结果,您可以使用以下方法。
SELECT #Module.*,users.UserName, isnull(#Access.HasAccess ,0) as HasAccess
FROM #Module
cross join (select distinct Username from #Access) users
left join #Access on #Module.id = #Access.id and users.username = #Access.UserName
结果集
ID Name UserName HasAccess
----------- -------------------- -------------------- ---------
1 Module 1 User 1 0
2 Module 2 User 1 1
3 Module 3 User 1 0
4 Module 4 User 1 0
5 Module 5 User 1 1
1 Module 1 User 2 0
2 Module 2 User 2 0
3 Module 3 User 2 1
4 Module 4 User 2 0
5 Module 5 User 2 0