Heim > Fragen und Antworten > Hauptteil
Ich habe diese 3 Tische:
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));
Ich möchte die Zeilen aus der Berichtstabelle abrufen, die mindestens eine der folgenden Bedingungen erfüllen:
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
Zuerst erstelle ich einen neuen Bericht, der öffentlich zugänglich ist:
insert into reports values(null, 'report 1 open to all', 1);
Dann kann auf einen anderen Bericht nur mit user_id = 1 zugegriffen werden:
insert into reports values(null, 'report 2 only for user_id 1', 0); insert into report_users values(null, 2, 1);
Dann kann auf den anderen Bericht nur über group_id=1 zugegriffen werden
insert into reports values(null, 'report 3 only for group_id 1', 0); insert into report_groups values(null, 3, 1);
Jetzt habe ich 3 Zeilen: Auf jede kann zugegriffen werden, auf eine Zeile kann nur mit user_id = 1 zugegriffen werden und auf eine andere Zeile kann nur mit group_id = 1 zugegriffen werden.
Geben Sie mir alle Zeilen an, in denen user_id = 1 ist:
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) ;
Ich habe 2 Reihen. Es klappt.
Geben Sie mir alle Zeilen mit 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) ;
Ich habe 2 Reihen. Es klappt.
Aber. Wenn „report_users“ oder „report_groups“ leer sind, erhalte ich keine Ergebnisse. Ich führe zuerst diese Abfrage aus:
truncate table report_groups;
Wenn ich dieselbe Abfrage wie zuvor ausführe, erhalte ich einen leeren Satz. Warum? Eigentlich sieht es nicht so aus, als gäbe es einen Unterschied zwischen der Benutzer-ID und der Gruppen-ID, die ich sende. Ich bekomme immer 0 Zeilen.
Mir kommt es so vor, als ob ich keine Ergebnisse erhalte, nur weil eine der beiden Tabellen leer ist. Stimmt etwas mit der Abfrage selbst nicht?
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 = ?);