Query Problem

Query Problem

am 03.03.2006 17:52:39 von Sebastian Gerecke

Hallo

Sicher eine Anfängerfrage, aber ich lerne noch, und bitte um Nachsicht.

Also, ich habe drei Tabellen (buch, aut, b2a). Die erste speichert Bücher
(bid, name), die zweite Autoren (aid, name) und die dritte die Relationen
(bid, aid). Jedes Buch kann mehrere Autoren, jeder Autor mehrere Bücher
haben.
Nun meine Frage: Wie finde ich alle Bücher, die von mehreren Autoren
geschrieben wurden, also z.B "aut.name = 'Adam' and aut.name = 'Bert'". Ich
habe auch schon gesucht, aber in den Beschreibungen wird immer nur nach
einem Autor gesucht :).

Danke
Sebastian

Re: Query Problem

am 04.03.2006 09:26:20 von newsgroup

Sebastian Gerecke schrieb:
> Hallo
>
> Sicher eine Anfängerfrage, aber ich lerne noch, und bitte um Nachsicht.
>
> Also, ich habe drei Tabellen (buch, aut, b2a). Die erste speichert Bücher
> (bid, name), die zweite Autoren (aid, name) und die dritte die Relationen
> (bid, aid). Jedes Buch kann mehrere Autoren, jeder Autor mehrere Bücher
> haben.
> Nun meine Frage: Wie finde ich alle Bücher, die von mehreren Autoren
> geschrieben wurden, also z.B "aut.name = 'Adam' and aut.name = 'Bert'". Ich
> habe auch schon gesucht, aber in den Beschreibungen wird immer nur nach
> einem Autor gesucht :).
>
> Danke
> Sebastian


Hallo,
"aut.name = 'Adam' and aut.name = 'Bert'"

wird wohl nicht funktionieren, weil diese Bedingung nie erfüllt wäre.
Entweder das Feld enthält Adam oder Bert aber nicht beides gleichzeitig.
Etwas anders wäre es bei

name = "Adam" and vorname = "Bert".

Was Du suchst ist entweder

"(aut.name = 'Adam' or aut.name = 'Bert')"

wenn Du noch mehr Bedingungen abprüfst, muss Du bei Mischung aus and und
or auf die Schaltlogik achten. Sonst kommen lustige Ergebnisse raus.

Oder Du verwendest

name in ('Adam', 'Bert', 'Gerecke')

was ich persönlich übersichtlicher finde.

Aber mich wundert schin, dass solche Basics nicht in Deinem Handbuch
stehen....

Gruß,
Michael

Re: Query Problem

am 04.03.2006 10:07:28 von Thomas Rachel

Sebastian Gerecke wrote:

> Also, ich habe drei Tabellen (buch, aut, b2a). Die erste speichert
> Bücher (bid, name), die zweite Autoren (aid, name) und die dritte die
> Relationen (bid, aid). Jedes Buch kann mehrere Autoren, jeder Autor
> mehrere Bücher haben.

> Nun meine Frage: Wie finde ich alle Bücher, die von mehreren Autoren
> geschrieben wurden, also z.B "aut.name = 'Adam' and aut.name = 'Bert'".

Hm, da mußt Du 2x joinen:

select ... from b2a AS a1 JOIN b2a AS a2 ON (a1.bid=a2.bid AND a1.aid !=
a2.aid);

(nicht getestet, Schuß ins Blaue)


HTH,

Thomas
--
Man kann nicht vorsichtig genug sein. Vielleicht müssen wir eine zweite
Sprache entwickeln. Die erste ist ja bald von Markeninhabern komplett
belegt. (Uwe Becker, de.soc.recht.misc, 2000-10-28)

Re: Query Problem

am 04.03.2006 12:37:28 von Sebastian Gerecke

Hallo,

danke schonmal für die Mühe, aber ich hab das Problem scheinbar noch nicht
richtig rüberbringen können. Sorry :) .

Also, nehmen wir an, ich suche ein Buch mit Autor "Adam", dann lautet die
Query :

select buch.name, aut.name
from buch, b2a, aut
where buch.bid = b2a.bid and b2a.aid = aut.aid and (aut.name = 'Adam'); ,
bzw "(aut.name = 'Adam' or aut.name = 'Bert')" für alle Bücher die von Adam
ODER Bert geschrieben wurden.

Soweit kein Problem, das verstehe ich :-).
Aber was ich eigentlich möchte, ist alle Bücher zu finden, die von Adam UND
Bert gemeinsam geschrieben sind, also Bücher mit mindestens zwei Autoren.

Ein einfaches AND in der Query bringt mich da nicht weiter, schon klar, da
nicht beide Bedingungen gleichzeitig wahr sein können. Aber wie mache ich
es dann ?

Danke
Sebastian

Michael König wrote:

> Sebastian Gerecke schrieb:
>> Hallo
>>
>> Sicher eine Anfängerfrage, aber ich lerne noch, und bitte um Nachsicht.
>>
>> Also, ich habe drei Tabellen (buch, aut, b2a). Die erste speichert Bücher
>> (bid, name), die zweite Autoren (aid, name) und die dritte die Relationen
>> (bid, aid). Jedes Buch kann mehrere Autoren, jeder Autor mehrere Bücher
>> haben.
>> Nun meine Frage: Wie finde ich alle Bücher, die von mehreren Autoren
>> geschrieben wurden, also z.B "aut.name = 'Adam' and aut.name = 'Bert'".
>> Ich habe auch schon gesucht, aber in den Beschreibungen wird immer nur
>> nach einem Autor gesucht :).
>>
>> Danke
>> Sebastian
>
>
> Hallo,
> "aut.name = 'Adam' and aut.name = 'Bert'"
>
> wird wohl nicht funktionieren, weil diese Bedingung nie erfüllt wäre.
> Entweder das Feld enthält Adam oder Bert aber nicht beides gleichzeitig.
> Etwas anders wäre es bei
>
> name = "Adam" and vorname = "Bert".
>
> Was Du suchst ist entweder
>
> "(aut.name = 'Adam' or aut.name = 'Bert')"
>
> wenn Du noch mehr Bedingungen abprüfst, muss Du bei Mischung aus and und
> or auf die Schaltlogik achten. Sonst kommen lustige Ergebnisse raus.
>
> Oder Du verwendest
>
> name in ('Adam', 'Bert', 'Gerecke')
>
> was ich persönlich übersichtlicher finde.
>
> Aber mich wundert schin, dass solche Basics nicht in Deinem Handbuch
> stehen....
>
> Gruß,
> Michael

Re: Query Problem

am 04.03.2006 13:56:34 von Sebastian Gerecke

Hallo,

ich habs gefunden (Alle Bücher mit den Autoren Adam UND Bert) :

select name from buch,
(select b2a.bid as id from b2a, aut where b2a.aid = aut.id and aut.name =
'Adam') as a1,
(select b2a.bid as id from b2a, aut where b2a.aid = aut.id and aut.name =
'Bert') as a2
where a1.id = a2.id and buch.id = c1.id;

Das ist aber NICHT schön :). Fällt vielleicht jemandem eine kürzere und
effizientere Query ein, die dasselbe leistet? Vor allem, wenn ich nach mehr
als zwei oder drei Autoren suchen muß, vielleicht nach fünf oder 10, wird
die Query sehr lang und unübersichtlicht.

Danke
Sebastian

Sebastian Gerecke wrote:

> Hallo,
>
> danke schonmal für die Mühe, aber ich hab das Problem scheinbar noch nicht
> richtig rüberbringen können. Sorry :) .
>
> Also, nehmen wir an, ich suche ein Buch mit Autor "Adam", dann lautet die
> Query :
>
> select buch.name, aut.name
> from buch, b2a, aut
> where buch.bid = b2a.bid and b2a.aid = aut.aid and (aut.name = 'Adam'); ,
> bzw "(aut.name = 'Adam' or aut.name = 'Bert')" für alle Bücher die von
> Adam ODER Bert geschrieben wurden.
>
> Soweit kein Problem, das verstehe ich :-).
> Aber was ich eigentlich möchte, ist alle Bücher zu finden, die von Adam
> UND Bert gemeinsam geschrieben sind, also Bücher mit mindestens zwei
> Autoren.
>
> Ein einfaches AND in der Query bringt mich da nicht weiter, schon klar, da
> nicht beide Bedingungen gleichzeitig wahr sein können. Aber wie mache ich
> es dann ?
>
> Danke
> Sebastian

Re: Query Problem

am 04.03.2006 16:07:45 von Axel Schwenke

Sebastian Gerecke wrote:
>
> danke schonmal für die Mühe, aber ich hab das Problem scheinbar noch nicht
> richtig rüberbringen können. Sorry :) .
>
> Also, nehmen wir an, ich suche ein Buch mit Autor "Adam", dann lautet die
> Query :
>
> select buch.name, aut.name
> from buch, b2a, aut
> where buch.bid = b2a.bid and b2a.aid = aut.aid and (aut.name = 'Adam'); ,
> bzw "(aut.name = 'Adam' or aut.name = 'Bert')" für alle Bücher die von Adam
> ODER Bert geschrieben wurden.

Du solltest dir besser JOIN statt "," angewöhnen. Dann wird die Query
auch gleich viel übersichtlicher:

SELECT buch.name, aut.name
FROM buch
JOIN b2a ON buch.bid = b2a.bid
JOIN aut ON b2a.aid = aut.aid
WHERE aut.name = 'Adam'

> Aber was ich eigentlich möchte, ist alle Bücher zu finden, die von Adam UND
> Bert gemeinsam geschrieben sind, also Bücher mit mindestens zwei Autoren.

Das sind zwei verschiedene Fragen:

a) Bücher, bei denen sowohl Adam als auch Bert Author sind
b) Bücher mit mindestens zwei Authoren

und man könnte noch weitere Fragen ableiten:

c) Bücher, bei denen genau Adam und Bert Author sind (also kein
weiterer)
d) Bücher mit *genau* zwei Authoren

> Ein einfaches AND in der Query bringt mich da nicht weiter, schon klar, da
> nicht beide Bedingungen gleichzeitig wahr sein können. Aber wie mache ich
> es dann ?

Indem du *zweimal* JOINst. Ich zeige mal exemplarisch a)

SELECT buch.name, aut1.name, aut2.name
FROM buch
JOIN b2a AS v1 ON v1.bid = buch.bid
JOIN aut AS aut1 ON aut1.aid = v1.aid
JOIN b2a AS v2 ON v2.bid = buch.bid
JOIN aut AS aut2 ON aut2.aid = v2.aid
WHERE aut1.name = 'Adam'
AND aut2.name = 'Bert'

Der Trick besteht hierbei darin, daß man eine Tabelle mehrfach in einem
JOIN verwenden kann, wenn man ihr per AS einen Aliasnamen gibt.

Über b) bis d) solltest du jetzt selber mal nachdenken.

Tips:

für b) und d) brauchst du COUNT() und GROUP BY, außerdem HAVING.

c) näherst du dich besser schrittweise. Als ersten Versuch formuliere
die folgende Frage in SQL: "zeige mir alle Bücher, die einen Author
Adam und einen Author Bert besitzen und einen Author, der weder Adam
noch Bert heißt". Dann schaust du dir mal an, wie man LEFT JOIN benutzt
um Zeilen zu finden, die *kein* Äquivalent in der anderen Tabelle haben
und wendest das auf die gerade gebildete Query an.

Und nicht gleich aufgeben, c) ist etwas knifflig.


XL

Re: Query Problem

am 05.03.2006 12:09:08 von Sebastian Gerecke

Hallo,

Axel Schwenke wrote:

>
> a) Bücher, bei denen sowohl Adam als auch Bert Author sind

a) Ist eigentlich schon so ziemlich genau das, was ich wollte.

>> Ein einfaches AND in der Query bringt mich da nicht weiter, schon klar,
>> da nicht beide Bedingungen gleichzeitig wahr sein können. Aber wie mache
>> ich es dann ?
>
> Indem du *zweimal* JOINst. Ich zeige mal exemplarisch a)
>
> SELECT buch.name, aut1.name, aut2.name
> FROM buch
> JOIN b2a AS v1 ON v1.bid = buch.bid
> JOIN aut AS aut1 ON aut1.aid = v1.aid
> JOIN b2a AS v2 ON v2.bid = buch.bid
> JOIN aut AS aut2 ON aut2.aid = v2.aid
> WHERE aut1.name = 'Adam'
> AND aut2.name = 'Bert'
>
> Der Trick besteht hierbei darin, daß man eine Tabelle mehrfach in einem
> JOIN verwenden kann, wenn man ihr per AS einen Aliasnamen gibt.

Danke, danke, danke :-))
Das ist die Lösung nach der ich gesucht habe. Ich war ja selbst schon auf ne
Lösung mit Subqueries in der from-clause gekommen, aber diese hier ist
einfacher und locker mal um den Faktor 50 schneller, nach ersten Test
zumindestens. Das man mehrfach joinen kann, wußte ich in der Tat nicht,
aber es ist ein super Hinweis!

Vielen Dank nochmal für die Hilfe,
mfg
Sebastian