如何检查一对多映射中是否存在特定映射 table

How to check if a particular mapping exists in a one-to-many mapping table

我有一个 table 维护 EMPLOYEE_ID 到可以分配给员工的一个或多个 ROLE_ID 的映射。 ROLE_IDROLE table 的主键。

现在,我正在尝试查找某个员工是否是团队负责人 (ROLE_ID = 2)。也就是说,从本质上讲,试图找出 (EMPLOYEE_ID, 2) 的特定映射组合是否存在于映射 table.

目前,我正在使用以下查询来实现此目的:

SELECT E.NAME AS `EMPLOYEE_NAME`, 
 EXISTS( SELECT 1 FROM `EMPLOYEE_ROLE` WHERE 
   (`EMPLOYEE_ROLE`.`EMPLOYEE_ID` = `E`.`EMPLOYEE_ID`)
   AND (`EMPLOYEE_ROLE`.`ROLE_ID` = 2)) AS `IS_TEAM_LEADER`
 -- Assume some other column shall be selected from ER table, 
 -- hence necessitating the JOIN on ER
FROM EMPLOYEE E
JOIN EMPLOYEE_ROLE ER ON (ER.EMPLOYEE_ID = E.EMPLOYEE_ID)
GROUP BY E.EMPLOYEE_ID;

虽然这似乎可以完成工作,但我正在寻找一种更有效的方法,因为当前形式的子查询似乎是多余的。不确定它是否相关,但是可以使用 FIND_IN_SET 或类似的函数吗?

任何人都可以提出解决方案,因为我对性能最佳的方法感兴趣吗?

编辑 1:我有意使用 JOIN EMPLOYEE_ROLE,目的是也可以从 ER table 中选取其他列。所以,我正在寻找优化子查询,同时保持连接不变。因此,语句 "current subquery in its current form seems redundant".

SQLFiddle:http://sqlfiddle.com/#!9/2aad3/5

使用 exists 子查询或使用 join,但不应在一个查询中同时使用两者。

我会使用连接方法,因为在必要时很容易获得与角色相关的数据:

SELECT E.NAME AS `EMPLOYEE_NAME`, 
FROM EMPLOYEE E
INNER JOIN EMPLOYEE_ROLE ER ON (ER.EMPLOYEE_ID = E.EMPLOYEE_ID)
WHERE ER.ROLE_ID=2;

如果您需要一个包含所有员工的列表,其中有一个字段指示该员工是否是 IS 领导者,请使用左连接而不是内部连接:

SELECT DISTINCT E.NAME AS `EMPLOYEE_NAME`, IF(ER.ROLE_ID IS NULL, 'NOT IS Leader','IS Leader') AS IsISLeader
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE_ROLE ER ON ER.EMPLOYEE_ID = E.EMPLOYEE_ID AND ER.ROLE_ID=2;

"best performing" --

CREATE TABLE `EMPLOYEE_ROLE` (
  `EMPLOYEE_ID` INT NOT NULL,
  `ROLE_ID` INT NOT NULL,
  PRIMARY KEY(`EMPLOYEE_ID`, ROLE_ID),
  INDEX(`ROLE_ID` EMPLOYEE_ID)
) ENGINE=InnoDB;

Why.

除此之外,请参阅@Shadow 的回答。

我在 SQL 中包含 EMPLOYEE_ID 以防发现不同 EMPLOYEE_ID 的相同名称,如果某些员工没有角色,也使用 LEFT JOIN:

SELECT E.EMPLOYEE_ID, E.NAME, SUM(IF(R.ROLE_ID=2,1,0)) IS_TEAM_LEADER
FROM EMPLOYEE E
LEFT JOIN EMPLOYEE_ROLE R ON E.EMPLOYEE_ID = R.EMPLOYEE_ID
GROUP BY 1,2

简单使用FK关系 创建角色 Table 为

table role{
RoleID
RoleName
Status
...}

并将员工 table 编辑为

table employee{
ID
name
...
}

创建table 员工角色

table employeerole{
ID
roleID
employeeID

}

现在您也可以使用规范化规则为每个员工管理多个角色

现在您可以使用查询

SELECT employee.ID, employee.Name, employeerole.roleid FROM role 
INNER   JOIN employeerole ON role.RoleID = employeerole.roleid INNER
JOIN   dbo.employee ON dbo.employeerole.employeeid = dbo.employee.ID 
WHERE   employeerole.roleid = 2

table 角色的 ID 为 2,名称例如是组长或经理

现在此查询已完全优化,将为您提供最佳结果

如果我没理解错的话,您是在尝试获取所有员工及其所有角色,以及一个额外的列来表明他们是否是团队领导。如果是这样,您只需要加入 EMPLOYEE_ROLE 两次,第二次是 LEFT JOIN 只是为了检查特定角色:

SELECT E.NAME, ER.ROLE_ID, ER2.EMPLOYEE_ID IS NOT NULL AS `IS_TEAM_LEADER`
  FROM EMPLOYEE E
  JOIN EMPLOYEE_ROLE ER ON ER.EMPLOYEE_ID = E.EMPLOYEE_ID
  LEFT JOIN EMPLOYEE_ROLE ER2 ON ER2.EMPLOYEE_ID = E.EMPLOYEE_ID AND ER2.ROLE_ID = 2;

SQL Fiddle: http://sqlfiddle.com/#!9/2aad3/9/0

这是获取属于特定角色的所有员工的查询

SELECT e.NAME FROM EMPLOYEE e right join (SELECT EMPLOYEE_ID FROM
EMPLOYEE_ROLE WHERE ROLE_ID=2) er using(EMPLOYEE_ID);