Programmieren - alles kontrollieren 4.940 Themen, 20.676 Beiträge

SQL Abfrage

Anwender / 11 Antworten / Baumansicht Nickles

Hallo Leute, ich habe ein ähnliches Problem wie logo3.
Ich kriege die Abfrage einfach nicht hin.

Situation
*********

Habe 3 Tabellen:

- tblInterpret (IDInterpret, Interpret)
- tblKategorie (IDKategorie, Kategorie)
- tblInterpret2Kategorie (fIDInterpret, fIDKategorie)

In der Tabelle tblInterpret2Kategorie werden den Interpreten verschiedene Kategorie zugewiesen.

Gewünschte Abfrage
*******************

Die Abfrage soll folgende Spalten enthalten:

- Interpret
- Anzahl Katgorie (in vielen Kategorien er zugeordnet ist)

Zusätzlich soll die Abfrage durch die Bedingung fIDKategorie=X eingeschränkt werden. (X steht für eine beliebige Kategorie).

Ich würde mich sehr über Hilfe freuen. Danke.

Anwender

bei Antwort benachrichtigen
d-oli Anwender „SQL Abfrage“
Optionen

Hallo

So was in der Art ...?


drop table tblInterpret;
drop table tblKategorie;
drop table tblInterpret2Kategorie;

create table tblInterpret
(
   IDInterpret NUMBER,
   Interpret VARCHAR2( 255 )
);

create table tblKategorie
(
   IDKategorie NUMBER,
   Kategorie VARCHAR2( 255 )
);

create table tblInterpret2Kategorie
(
   fIDInterpret NUMBER,
   fIDKategorie NUMBER
);

insert into tblInterpret values( 1, 'AC/DC' );
insert into tblInterpret values( 2, 'ABBA' );

insert into tblKategorie values( 1, 'Rock' );
insert into tblKategorie values( 2, 'Hard Rock' );
insert into tblKategorie values( 3, 'Pop' );

insert into tblInterpret2Kategorie values( 1, 1 );
insert into tblInterpret2Kategorie values( 1, 2 );
insert into tblInterpret2Kategorie values( 2, 3 );

commit;

select i.Interpret, count( i2k.fIDInterpret ) from tblInterpret2Kategorie i2k
join tblInterpret i
on i.IDInterpret = i2k.fIDInterpret
join tblKategorie k
on i2k.fIDKategorie = k.IDKategorie
and ( k.Kategorie = 'Rock' or k.Kategorie = 'Hard Rock' )
group by i.Interpret;



d-oli
Konstruktive Kritik zeichnet sich dadurch aus, dass sie höflich, nützlich und sachlich ist.
bei Antwort benachrichtigen
Anwender d-oli „Hallo So was in der Art ...? drop table tblInterpret drop table tblKategorie...“
Optionen

Vielen Dank erstmal. Leider kann ich die Abfrage in meiner Access DB nicht ausführen (Fehler in der FROM Klausel).
Wie muss die Abfrage für Access aussehen?

bei Antwort benachrichtigen
d-oli Anwender „Vielen Dank erstmal. Leider kann ich die Abfrage in meiner Access DB nicht...“
Optionen

muss ein as vor dem Alias hin?

from tblInterpret2Kategorie as i2k

d-oli

Konstruktive Kritik zeichnet sich dadurch aus, dass sie höflich, nützlich und sachlich ist.
bei Antwort benachrichtigen
Anwender d-oli „muss ein as vor dem Alias hin? from tblInterpret2Kategorie as i2k d-oli“
Optionen

nö, das isses nicht. Kann es sein, dass die beiden JOIN's noch verklammert werden müssen? (JOIN's verwirren mich immer wieder)

bei Antwort benachrichtigen
d-oli Anwender „nö, das isses nicht. Kann es sein, dass die beiden JOIN s noch verklammert...“
Optionen

Ach so ...

Musst du bei Access ev. immer INNER JOIN schreiben?

PS:
JOIN's noch verklammert werden
Tatsächlich!!! Habe in der Access-Hilfe nachgesehen. Oh Gott ... viel Spass damit ... ;-)

Konstruktive Kritik zeichnet sich dadurch aus, dass sie höflich, nützlich und sachlich ist.
bei Antwort benachrichtigen
Anwender d-oli „Hallo So was in der Art ...? drop table tblInterpret drop table tblKategorie...“
Optionen

Ich hab mal ein Teil der Abfrage in Access erstellen lassen:

SELECT tblInterpret.Interpret, Count(tblInterpret2Kategorie.ID) AS AnzahlvonID
FROM tblKategorie INNER JOIN (tblInterpret INNER JOIN tblInterpret2Kategorie ON tblInterpret.IDInterpret = tblInterpret2Kategorie.fIDInterpret) ON tblKategorie.IDKategorie = tblInterpret2Kategorie.fIDKategorie
GROUP BY tblInterpret.Interpret;

Diese Abfrage liefert in der ersten Spalte alle Interpreten und in der zweiten Spalte die Anzahl Kategorien, welchen die Interpreten zugeordnet sind.

Das Problem allerdings kommt jetzt, wenn ich die Abfrage zusätzlich nach fIDKategorie einschränken will.
Habe das wieder durch Access erstellen lassen:

SELECT tblInterpret.Interpret, Count(tblInterpret2Kategorie.ID) AS AnzahlvonID, tblInterpret2Kategorie.fIDKategorie
FROM tblKategorie INNER JOIN (tblInterpret INNER JOIN tblInterpret2Kategorie ON tblInterpret.IDInterpret = tblInterpret2Kategorie.fIDInterpret) ON tblKategorie.IDKategorie = tblInterpret2Kategorie.fIDKategorie
GROUP BY tblInterpret.Interpret, tblInterpret2Kategorie.fIDKategorie
HAVING tblInterpret2Kategorie.fIDKategorie=2;

Jetzt werden zwar nur Interpreten der Kategorie ID=2 angezeigt, aber in der zweiten Spalte (Anzahl Kategorien) wird überall der Wert 1 angezeigt, obwohl mehrere dieser Interpreten in mehr als nur einer Kategorie zugeordnet sind. Wie muss die Abfrage heissen, damit auch in der Spalte 2 (Anzahl Kategorien) der richtige Wert angezeigt wird?

Anwender

bei Antwort benachrichtigen
Borlander Anwender „Ich hab mal ein Teil der Abfrage in Access erstellen lassen: SELECT...“
Optionen
Jetzt werden zwar nur Interpreten der Kategorie ID=2 angezeigt, aber in der zweiten Spalte (Anzahl Kategorien) wird überall der Wert 1 angezeigt, obwohl mehrere dieser Interpreten in mehr als nur einer Kategorie zugeordnet sind. Wie muss die Abfrage heissen, damit auch in der Spalte 2 (Anzahl Kategorien) der richtige Wert angezeigt wird?
Naja, die Abfrage liefert Dir genau das was was abgefragt wurde ;-)
Mit einem SubSelect kann man problemlos das gewünschte erreichen:

[...]
WHERE i.IDInterpret IN (
SELECT fIDInterpret FROM tblInterpret2Kategorie WHERE fIDKategorie=X
);

Gruß
Borlander
bei Antwort benachrichtigen
Anwender Borlander „ Naja, die Abfrage liefert Dir genau das was was abgefragt wurde - Mit einem...“
Optionen

Hab inzwischen die Lösung mit der SubSelect realisiert. Funktioniert wie gewünscht. Vielen Dank Borlander.

Kommt es mit SubSelect bei umfangreichen Tabellen zu spürbarer Performaceeinbussen?

bei Antwort benachrichtigen
Borlander Anwender „Hab inzwischen die Lösung mit der SubSelect realisiert. Funktioniert wie...“
Optionen

SubSelects sind genau wie auch JOINs (auch wenn die schnell noch teurer werden können weil hier das Kreuzprodukt mehrerer Tabellen gebildet werden muß) relativ teuer weil es erforderlich ist mehrere Tabellen ab zu fragen und Ergebnissmengen zwischen zu speichern...

Wichtig ist sinnvolle Indizierung, bei großen Tabellen und FullTable-Scans geht die Leistungs sonst in den Keller. Im hier vor liegenden Fall sollte jedes ID-Feld einen Index besitzen. Wenn das Feld bereits das erste Feld des Primary-Keys ist reicht das, ansonsten einen für das Feld einrichten...

Gruß
Borlander

bei Antwort benachrichtigen
Borlander Anwender „SQL Abfrage“
Optionen

Warum joint ihr alle so wild herum? JOINs sind teuer und wenn wir die Kategorienamen nicht benötigen dann können wir auf tblKategorie bestens verzichten...

SELECT Interpret, COUNT(*) AS AnzahlCat
FROM tblInterpret AS i LEFT JOIN tblInterpret2Kategorie AS ik ON i.IDInterpret=ik.fIDInterpret
GROUP BY Interpret
WHERE ik.fIDKategorie=X;

Das bei Einschränkung auf eine Kategorie jeder Interpret natürlich nur einmal auftaucht hast Du wie es scheint bereits festgestellt ;-)


Gruß
Borlander

bei Antwort benachrichtigen
Anwender Borlander „Warum joint ihr alle so wild herum? JOINs sind teuer und wenn wir die...“
Optionen

Vielen Dank für deine Vorschläge.
Ich habe versucht die Abfrage nach deinem Beispiel zusammen zu stellen, erhalte allerdings eine Fehlermeldung: "Syntaxfehler (fehlender Operator in Abfrageausdruck 'Interpret WHERE ik.fIDKategorie'

Ich komme nicht weiter.

Anwender

bei Antwort benachrichtigen