Mysql 左外部联接,WHERE子句和联合
我有三张桌子:Mysql 左外部联接,WHERE子句和联合,mysql,left-join,outer-join,Mysql,Left Join,Outer Join,我有三张桌子: Users: Depts Default | fid | uid | rights | | fid | did | rights | | fid | rights | |-----+-----+--------| |-----+-----+--------| |-----+--------| | 1 | 1 | 4 | | 1 | 10 | 2 | | 1 |
Users: Depts Default
| fid | uid | rights | | fid | did | rights | | fid | rights |
|-----+-----+--------| |-----+-----+--------| |-----+--------|
| 1 | 1 | 4 | | 1 | 10 | 2 | | 1 | 2 |
| 3 | 1 | 4 | | 2 | 10 | 2 | | 2 | 4 |
+--------------------+ +--------------------+ +--------------+
这些定义了用户根据其用户ID和所属部门对系统中文件的访问权限。访问文件时,有效权限按默认权限(如果有)的顺序确定,默认权限由部门权限(如果有)覆盖,而部门权限又由用户权限(如果有)覆盖
因此,在此示例中,部门10的成员用户1没有文件2的用户权限,但从其部门获得权限级别2。(默认权限4不适用,因为它们被部门权限覆盖)
我需要查询此表结构以确定用户对一个或多个文件的有效权限。最初,我唯一的要求是一次获取一个文件的有效权限,我通过为三个子查询中的每一个子查询分配优先级,按优先级顺序将它们与UNION
组合,然后只获取第一个结果,如下所示:
select a.rights from
(select 100 as priority, rights from `Users` where `uid`=1 and `fid` = 2 union
select 200 as priority, rights from `Depts` where `did`=10 and `fid` = 2 union
select 300 as priority, rights from `Default` where `fid` = 2
) as a
order by priority asc limit 1;
现在,这可能不是特别有效,但到目前为止已经奏效了
我现在的问题是扩展它以检索用户对多个文件的有效权限。由于优先级结构的原因,这无法通过现有查询完成 我应该能够跨三个表使用
完全外部连接
,生成一组权限值,我可以合并
,但MySQL不支持完全外部连接
在对堆栈溢出和其他地方进行了深入研究之后,我得出了以下结论(UID、部门ID和文件ID仅用于说明):
从表面上看,这似乎是可行的,但使用WHERE
子句会错误地过滤结果。从我的阅读来看,在子句上使用似乎是一个解决方案,但正确的语法让我大吃一惊
对于上面文件#2的示例,我希望得到
| fid | Users | Depts | Default |
+-----+-------+-------+---------+
| 2 | null | 2 | 4 |
+-----+-------+-------+---------+
当三个权限值合并时,这将提供有效权限2
这个查询很可能适用于这个简单的示例。测试中出现的问题是,一些应该包含的文件没有被包含
所以,我的问题是:
如何使用在子句上而不是WHERE
编写查询
作为奖励,有没有更好的方法达到同样的效果
作为一个脚注:这整个结构需要及时审查,但时间不是现在。这就是我必须处理的问题,直到后来的一些开发提示我们实现更好的东西。您可以通过将感兴趣的所有文件合并在一起,而不是使用where in
,来创建它们的内联视图。这将维护查询链的outer
nish
例如:
@GordonLinoff祝你胃口好。您刚刚遇到了一个具有挑战性的问题。是否有指定用户所在部门的内容?@pala_uu有一个单独的用户表提供该信息。文件表包含每个文件的类似信息。我真的看不出这有什么帮助。不过,处理权限表的代码无法访问这些表。对于某些查询来说,文件的数量可能很小,但我需要这样才能处理数百个文件。我可以通过编程生成所需的SELECT语句,但我忍不住认为一定有更好的方法。@HoboSapiens我假设,既然您可以通过编程将它们包含在中的中,那么构建联合就成了一件小事。或者,我能看到它发生的唯一方式是,如果你有一个包含所有文件的表,那么今天就晚了。我明天早上再看一遍,看看你的解决方案是否可行。那太容易了。我根本没有想到用这种方式来破解文件ID。正如您所说,我可以在PHP中预处理文件ID的SELECT语句。查询必须处理数百个文件。创建一个临时表来保存文件ID可能有什么好处,或者这是我需要尝试的东西吗?如果文件是已知数量的,那么是的,我可能会创建一个表来保存它们并为fid
| fid | Users | Depts | Default |
+-----+-------+-------+---------+
| 2 | null | 2 | 4 |
+-----+-------+-------+---------+
select files.fid, u.rights, d.rights, def.rights
from (
select 1 as fid
union all
select 2 as fid
union all
select 3 as fid
-- all the files you are interested in
) files
left join users u
on files.fid = u.fid
and u.uid = 2 -- put the user you are searching for here
left join depts d
on files.fid = d.fid
and d.did = 10 -- put the dept you are searching for here
left join `default` def
on files.fid = def.fid