首页 > 解决方案 > 有没有比在 where 子句中使用多个“AND”语句更有效的方法来比较两个表之间的多个值?

问题描述

我有两张桌子——</p>

表一是员工——包含一个员工记录,其中包含一个 id、活动状态和组织级别值(工作组)。

WG1 = company
WG2 = department
WG3 = cost center
WG4 = floor
WG5 = shift
WG6 = role

员工只有一条记录,并且每个字段中始终有一个值(不允许为空)

CREATE TABLE [dbo].[EMPLOYEES](
[EmpID] [int] IDENTITY(1,1) NOT NULL,
[ACTIVESTATUS] [smallint] NOT NULL,
[WG1] [smallint] NOT NULL,
[WG2] [smallint] NOT NULL,
[WG3] [smallint] NOT NULL,
[WG4] [smallint] NOT NULL,
[WG5] [smallint] NOT NULL,
[WG6] [smallint] NOT NULL)

INSERT INTO [dbo].[EMPLOYEES]
    ([FILEKEY],[ACTIVESTATUS],[WG1],[WG2],[WG3],[WG4],[WG5],[WG6])
VALUES
    (193,0,1,1,1,1,1,1)

表二是 Useraccess,它是一个用户表。此表表示用户拥有的组织访问权限,因此可以有多个记录。所有字段都有一个值,但是 0 代表全部。

CREATE TABLE [dbo].[USERACCESS](
[USERID] [int] IDENTITY(1,1) NOT NULL,
[WG1] [smallint] NOT NULL,
[WG2] [smallint] NOT NULL,
[WG3] [smallint] NOT NULL,
[WG4] [smallint] NOT NULL,
[WG5] [smallint] NOT NULL,
[WG6] [smallint] NOT NULL)
    

INSERT INTO [dbo].[USERACCESS]
       ([USERID],[WG1],[WG2],[WG3],[WG4],[WG5],[WG6])
VALUES
       (1927,0,0,0,1,0,0),
       (1927,1,1,1,0,1,2)
       

1927,0,0,0,1,0,0 = 使用轮班 (WG5) = 1 访问所有员工 1927,1,1,1,0,1,2 = 公司 1,部门 1,成本中心 1,全部楼层,班次 1,角色 2

此用户将有权根据第一个用户访问记录访问示例员工。

现在,为了确定用户是否有权访问特定员工,将使用如下脚本与单独比较的每个 WG 值进行比较,并检查该值是否为 0。

SELECT 0
,count(*)
FROM employees e
WHERE (e.activestatus = 0)
AND (
    (
        SELECT COUNT(*)
        FROM USERACCESS U
        WHERE (U.USERID = 1927)
            AND (
                (
                    (U.WG1 = E.WG1)
                    OR (U.WG1 = 0)
                    )
                AND (
                    (U.WG2 = E.WG2)
                    OR (U.WG2 = 0)
                    )
                AND (
                    (U.WG3 = E.WG3)
                    OR (U.WG3 = 0)
                    )
                AND (
                    (U.WG4 = E.WG4)
                    OR (U.WG4 = 0)
                    )
                AND (
                    (U.WG5 = E.WG5)
                    OR (U.WG5 = 0)
                    )
                AND (
                    (U.WG6 = E.WG6)
                    OR (U.WG6 = 0)
                    )
                )
        ) > 0
    )
UNION
SELECT 1
,count(*)
FROM employees e
WHERE (e.activestatus = 1)
AND (
    (
        SELECT COUNT(*)
        FROM USERACCESS U
        WHERE (U.USERID = 1927)
            AND (
                (
                    (U.WG1 = E.WG1)
                    OR (U.WG1 = 0)
                    )
                AND (
                    (U.WG2 = E.WG2)
                    OR (U.WG2 = 0)
                    )
                AND (
                    (U.WG3 = E.WG3)
                    OR (U.WG3 = 0)
                    )
                AND (
                    (U.WG4 = E.WG4)
                    OR (U.WG4 = 0)
                    )
                AND (
                    (U.WG5 = E.WG5)
                    OR (U.WG5 = 0)
                    )
                AND (
                    (U.WG6 = E.WG6)
                    OR (U.WG6 = 0)
                    )
                )
        ) > 0
    )
ORDER BY 1

这种类型的查询是最常执行的查询之一,因此在多次读取整个员工表时具有最高的读取次数,因此我正在寻找一个可能更有效地执行此操作的查询。

标签: sql-servertsqljoin

解决方案


推荐阅读