Ich habe 3 Tabellen - eine für Benutzer, eine für ihre eingehenden Zahlungen und eine für ihre ausgehenden Zahlungen. Ich möchte alle eingehenden und ausgehenden Zahlungen in einer einzigen Ergebnismenge anzeigen. Ich kann dies mit mehreren select
s und einem union
tun, aber es scheint umständlich, und ich vermute, es ist langsam aufgrund der Unterabfragen - und die Tabellen sind extrem groß (obwohl ich Indizes verwende). Gibt es einen schnelleren Weg, dies zu erreichen? Vielleicht mit einem full outer join
?MySQL optimiert eine Union-Abfrage mit einer Join-Abfrage statt
Hier ist eine vereinfachte Version des Schemas mit einigen Beispieldaten:
create table users (
id int auto_increment,
name varchar(20),
primary key (id)
) engine=InnoDB;
insert into users (name) values ('bob'),('fred');
create table user_incoming_payments (
user_id int,
funds_in int
) engine=InnoDB;
insert into user_incoming_payments
values (1,100),(1,101),(1,102),(1,103),
(2,200),(2,201),(2,202),(2,203);
create table user_outgoing_payments (
user_id int,
funds_out int
) engine=InnoDB;
insert into user_outgoing_payments
values (1,100),(1,101),(2,200),(2,201);
Und hier ist die hässliche suchen Abfrage, die das Ergebnis, das ich für Benutzer bob wollen erzeugt:
select * from (
(select u.name, i.funds_in, 0 as 'funds_out' from users u
inner join user_incoming_payments i on u.id = i.user_id)
union
(select u.name, 0 as 'funds_in', o.funds_out from users u
inner join user_outgoing_payments o on u.id = o.user_id)
) a where a.name = 'bob'
order by a.funds_in asc, a.funds_out asc;
Und hier ist so nah, wie ich mit join
s das gleiche Ding tun kann - es ist nicht korrekt obwohl, weil ich möchte, dass dieses Ergebnis gleich aussieht wie das vorherige und ich war mir nicht sicher, wie man full outer join
:
select *
from users u
right join user_incoming_payments i on u.id = i.user_id
right join user_outgoing_payments o on u.id = o.user_id
where u.name = 'bob';
In MySQL gibt es kein FULL OUTER JOIN - obwohl Sie das natürlich auf verschiedene Arten simulieren können. Aber wenn diese Abfrage das gewünschte Ergebnis erzeugt, dann ist ein FULL OUTER JOIN nicht das, was gewünscht wird. Ihre Anfrage ist in Ordnung (obwohl ich nicht sicher bin, dass die Super-Abfrage notwendig ist) – Strawberry
Haben Sie Beispieldaten und Ergebnisse? –
@Ivan: Sie können die Beispieldaten und Ergebnisse nicht bereits in der Frage sehen? Wenn nicht, liest du nicht sehr gründlich. –