Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Suche nach Tabelleneintrag mit Zweit-Tabelle

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von Papp Nase, 11 März 2014.

  1. Papp Nase

    Papp Nase Fleissiger Benutzer

    Hallo,

    ich habe eine Datenbank namens "tiere" mit zwei Tabellen

    haustiere (ID, Tier, Name, Besitzer)
    besitzer (ID, Name, Wohnort, Telefon)

    Folgende Beziehung: haustier(Besitzer) = besitzer(Name)

    Ich möchte alle Tiere (komplette Zeile) finden, die in einem Wohnort vorkommen:

    Folgender Ansatz

    Code:
    SELECT * FROM haustiere WHERE Name = "XYZ"
    
    Das funktioniert gut.

    Sortierung nach Namen, die in der gewünschten Stadt wohnen:

    Code:
    
    SELECT Name FROM besitzer WHERE Wohnort = "XYZ"
    
    
    klappt auch wunderbar.

    Nun die Kopplung:

    Code:
    SELECT * FROM haustiere WHERE Name = (SELECT Name FROM besitzer WHERE Wohnort = "XYZ")
    
    Das klappt nicht. Fehlermeldung: "#1242 - Subquery returns more than 1 row"

    Ist mein Ansatz mit den geschachtelten Abfragen so vom Ansatz richtig, nur dass vielleicht ein einfaches Schlüsselwort noch fehlt, damit Primärabfrage mehrere Einträge akzeptiert, oder ist die Vorgehensweise ganz anders? Die Sekundärabfrage müsste irgendwie mit einem OR an den Namen gekoppelt werden. Geht das?
     
  2. Hony%

    Hony% Datenbank-Guru

    Nein. Das mit dem Subselect und WHERE funktioniert bei einem solchen Ausdruck nur dann wenn ein singulärer Wert zurück gegeben wird.

    Was du in diesem Fall suchst ist ein JOIN:
    Code:
    SELECT T.*
    FROM haustiere AS T
    INNER JOIN besitzer AS B
    ON T.besitzer = B.name
    WHERE B.wohnort = 'XYZ'
    Mit Subselect geht es dann allerdings doch wenn du den Ausdruck änderst:
    Code:
    SELECT *
    FROM haustiere
    WHERE besitzer IN (
    SELECT name
    FROM besitzer
    WHERE wohnort = 'XYZ'
    )
    Die Zugriffskosten sind für den Join allerdings geringer. Darüber musst du dir beim lernen noch keine Gedanken machen. Das spielt erst bei großen Datenmengen eine Rolle.
     
    Zuletzt bearbeitet: 12 März 2014
  3. akretschmer

    akretschmer Datenbank-Guru


    Meep!

    Du hast eine ID in Besitzer, das ist sicherlich auch der primary Key. Die Verbindung in Haustiere zu besitzer sollte nun als Foreign Key in Haustiere auf die ID in Besitzer sein.

    Etwa so:

    Code:
    test=# create table besitzer(id int primary key, name text);
    CREATE TABLE
    test=*# create table tiere (id int primary key, besitzer int references besitzer, name text);
    CREATE TABLE
    
     
  4. Papp Nase

    Papp Nase Fleissiger Benutzer

    Danke fuer die Antwort.

    Dass hat funktioniert.
    Ich habe noch das Schlüsselwort ANY gefunden, dass geht auch:

    Code:
     SELECT * FROM haustiere WHERE Besitzer = ANY (SELECT Name FROM besitzer WHERE Wohnort = "XYZ") 
    Folgendes Problem hab ich beim Nachdenken festgestellt. Es könnte ja sein, dass es einen Namen doppelt gibt, aber mit zwei unterschiedlichen Adressen bei den Besitzern. Meinst Du damit:

    dass ich bei haustiere.besitzer nicht den dierekten Namen reinschreibe z.B. Frank oder Otto, sondern den PrimKey, den es nur einmal gibt und damit bei der Tabelle besitzer dann dem Namen zugeordnet werden kann?
     
  5. Papp Nase

    Papp Nase Fleissiger Benutzer

    Ich hab zum Spaß noch eine dritte Tabelle erstellt und mit Werten gefüllt:

    wildtiere (ID, Tier, Name, Besitzer)

    Ich habe jetzt versucht, in beiden Tiertabellen gleichzeitig nach Besitzern zu suchen:

    Code:
    SELECT * FROM (wildtiere AND haustiere) WHERE Besitzer = "Otto"
    .

    Das klappte leider nicht.

    Ich habe eine Frage - angenommen, ich mache eine Suche und möchte Ergebnisse zwischenspeichern. Es könnte ja sein, dass ich z.B. wissen möchte, wie viele Wildtiere und wie viele Haustiere ein Besitzer hat. In einer Programmiersprache würde ich mir eine kleine Variable erstellen, um ein Ergebnis zwischenzuspeichern. Könnte ich mir einfach eine kleine neue Tabelle erstellen, um Ergebnisse zwischenzuspeichern?

    Oben wurde ein Beispiel mit Join angeführt:
    SELECT T.* ... AS T

    Ist jetzt T. schon gewissermaßen eine Variable?

    Und verkürze ich mir damit die Datenbankzugriffe (und dadurch entstehende Traffickosten), weil ich mir die Ergebnisse so in den Speicher lade und weitere Bearbeitungen dann mit verkürzten Tabellen bzw. Tabellenausschnitten im Arbeitsspeicher erfolgen?
     
    Zuletzt bearbeitet: 13 März 2014
  6. Hony%

    Hony% Datenbank-Guru

    Genau das meint @akretschmer damit. In diesem Fall führt dann auch kein Weg am JOIN vorbei.

    In diesem Fall erzeugst du erst eine neue Menge aus haustiere und wildtiere. Wichtig ist dabei, dass die beiden Relationen die gleiche Anzahl Attribute hat. Anschließend kannst du die neue Menge wie eine Tabelle benutzen:
    Code:
    SELECT *
    FROM (
        SELECT * FROM haustiere
        UNION
        SELECT * FROM wildtiere
    ) AS T
    WHERE Besitzer = "Otto";
    Das kannst du mit einer View erreichen:
    Code:
    CREATE VIEW Name_des_View AS
    SELECT * FROM haustiere;
    T ist ein Alias, also ein Name, für die erzeugte Menge. Traffickosten sollten möglichst nie entstehen wenn du mit einer Datenbank arbeitest. Bei einer lokalen Datenbank ist das auch nicht der Fall.

    Mit Hilfe von Views kannst du komplizierte Abfragen vorbereiten und dann wie eine Tabelle benutzen. Da eine VIEW immer neu erzeugt wird reduziert das nicht die Zugriffskosten und auch nicht den Speicherbedarf. Das können nur Materialized Views leisten. Dazu sind aber tiefgreifende Kenntnisse notwendig. Außerdem wird das auch erst bei richtig großen Datenbanken notwendig.
     
  7. Papp Nase

    Papp Nase Fleissiger Benutzer

    Vielen Dank für Eure Antworten.

    Also meine Datenbank muss schon sehr groß sein. Bei den Wildtieren habe ich bereits 3 Elefanten drinnen und einen Löwe :)

    Was ist denn eigentlich eine "große" Datenbank? Wären 1000 Kundendaten in einer Firma schon groß?
     
  8. Hony%

    Hony% Datenbank-Guru

    Nicht einmal annähernd. Häng da mal noch so 3+ Nullen dran in 20+ Tabellen. Mach dir da am besten keine Gedanken. Optimiert wird erst wenn ein Flaschenhals spürbar wird. Alles Andere ist Zeitverschwendung.
     
  9. Papp Nase

    Papp Nase Fleissiger Benutzer

    Vielen Dank für Eure Antworten.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden