首页  >  问答  >  正文

如果其中一个表为空,mysql 中的查询给出 0 结果

我有这 3 个表:

create table reports(id int not null AUTO_INCREMENT,name varchar(255)not null,public_access tinyint not null,primary key (id));
create table report_users(id int not null AUTO_INCREMENT,report_id int not null,user_id int not null,primary key (id),foreign key (report_id) references reports(id));
create table report_groups(id int not null AUTO_INCREMENT,report_id int not null,group_id int not null,primary key (id),foreign key (report_id) references reports(id));

我想从报告表中获取至少满足以下条件之一的行:

1 - The field public_access is true
2 - The report is in the related table report_users with in parameter user_id 
3 - The report is in the related table report_groups with in parameter group_id

首先,我创建一个可公开访问的新报告:

insert into reports values(null, 'report 1 open to all', 1);

然后另一个报告只能由 user_id = 1 访问:

insert into reports values(null, 'report 2 only for user_id 1', 0);
insert into report_users values(null, 2, 1);

然后另一个报告只能由group_id = 1访问

insert into reports values(null, 'report 3 only for group_id 1', 0);
insert into report_groups values(null, 3, 1);

现在,我有 3 行:每一行都可以访问,一行只能由 user_id = 1 访问,另一行只能由 group_id = 1 访问。

给我 user_id = 1 的所有行:

select reports.* 
from reports, report_users,report_groups
where 
reports.public_access = 1
or
(report_users.report_id = reports.id and report_users.user_id = 1)
or
(report_groups.report_id = reports.id and report_groups.group_id = 5)
;

我得到 2 行。它有效。

给我 group_id = 1 的所有行:

select reports.* 
from reports, report_users,report_groups
where 
reports.public_access = 1
or
(report_users.report_id = reports.id and report_users.user_id = 4)
or
(report_groups.report_id = reports.id and report_groups.group_id = 1)
;

我得到 2 行。它有效。

但是。如果report_users或report_groups为空,我不会得到任何结果。我首先运行此查询:

truncate table report_groups;

当我运行与以前相同的查询时,我得到一个空集。为什么?实际上,看起来我发送的 user_id 和 group_id 没有任何区别。我总是会得到 0 行。

对我来说,似乎只是因为两个表之一是空的,所以我没有得到任何结果。 查询本身有问题吗?

P粉848442185P粉848442185402 天前424

全部回复(1)我来回复

  • P粉087951442

    P粉0879514422023-09-14 12:48:37

    你用这行代码做什么:

    from reports, report_users,report_groups

    是 3 个表的(旧式)CROSS JOIN,这意味着如果其中一个表为空,则结果也为空。

    而是使用EXISTS

    select r.* 
    from reports r
    where r.public_access = 1
       or exists (select * from report_users u where u.report_id = r.id and u.user_id = ?)
       or exists (select * from report_groups g where g.report_id = r.id and g.group_id = ?);

    回复
    0
  • 取消回复