Heim  >  Fragen und Antworten  >  Hauptteil

Die Abfrage in MySQL liefert 0 Ergebnisse, wenn eine der Tabellen leer ist

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粉848442185P粉848442185403 Tage vor428

Antworte allen(1)Ich werde antworten

  • 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 = ?);

    Antwort
    0
  • StornierenAntwort