SELECT 来自两个 table 的记录,其中行可能不存在于第二个 table 中(与 LEFT JOIN 相关)

SELECT records from two tables where rows might not present in the second table (related to LEFT JOIN)

我有两个 tables - ModuleAccess.

模块 - 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