UndSo: Mit INNER JOIN 3 Tabellen verbinden

Hallo Forum,
ich hatte mal im Archiv nach einer Query gefragt, die ich nun weiter ausbauen will.
Sprich, mit Hilfe von INNER JOIN 3 Tabellen verbinden. Mit hilde der Doku würde ich das bestimmt selber hinkriegen, mein Problem ist nur, dass ich in der 3'ten Tabelle einen coun(*) brauche.

Diese Query soll nun mit der dritten Tabelle erweitert werden:

select A.kategorie, A.name, A.beschreibung, A.themen, A.antworten, MAX(B.thumbname)
from präfix_galerie AS A
INNER JOIN präfix_galeriebilder AS B on A.kategorie=B.kategorie
GROUP BY A.kategorie, A.name, A.beschreibung, A.themen, A.antworten
;

Von der dritten Tabelle, die präfix_kommentare heißt, brauche ich den count(*), wieviele Kommentare (Zeilen) von "where C.userid=1" in der Spalte Userid vorhanden sind.

A.kategorie=B.kategorie

A.galerieid=B.galerieid=C.galerieid

Eine Frage noch nebenbei. Habe pro Tabelle Testweise zurzeit vielleicht 10 Zeilen drin.
Wenn man die obere Query abfrage, braucht er ungefähr 0.03.. Sekunden. Das ist normalerweise schlecht ne?
Müsste nochmal nachschauen, nicht dass ich mich verschaut habe uns es 0.003.. Sekunden sind.

Wenn ich A.galerieid=B.galerieid=C.galerieid für die neue Query nehme, dann setze ich den PrimaryKey für alle drei Tabellen auf galerieid.

  • Wäre es von der Perfomance eher schlecht, bzw. überhaupt sinnvoll, wenn ich für die Tabelle präfix_kommentare 2 Primary Keys setze? Diese Query von oben greift dann immer auf galerie zu. In einer anderen Stelle der Community brauce ich dann noch sehr oft die Spalte kommentarid von der Tabelle präfix_kommentare
  • Meine letzte Frage noch, dass ich das mit dem index kapiere. Wir haben eine Geo_Tabelle, mit PLZ, Stadt usw. Jede Zeile hat eine eindeutige id, deshalb ist für id ein inex gesetzt. Nun meine Frage. Wenn nun ab und zu mal ein paar Zeilen von der Geo_Tabelle gelöscht werden (aus was für einem Grund auch immer) und neue Zeilen eingefügt werden mit fortlaufender ID, wäre dann ein Index besser oder ein Primary Key?
    Ich habe irgendwo mal gelesen, dass es nicht gut sei, wenn man Zeilen löscht, wenn ein Index gesetzt ist.

Viele Grüße
undso

  1. yo,

    welches dbms und welche version ? beispieldaten angeben, sowohl inhalte der tabellen als auch das gewünschte result.

    Von der dritten Tabelle, die präfix_kommentare heißt, brauche ich den count(*), wieviele Kommentare (Zeilen) von "where C.userid=1" in der Spalte Userid vorhanden sind.

    wie du diesen COUNT einbaust, ist abhängig von deinem dbms und der version. deswegen ist es immer wichtig, diesen zu kennen. desweiteren ist es interessant zu wissen, wo die selektion C.userid=1 stattfinden soll, sprich ob sie sich auf die ganze query auswirken soll oder nur auf den count. deswegen sind beispiele so wichtig, weil sie meistens für uns mehr aussagen als erklärungen.

    Wenn man die obere Query abfrage, braucht er ungefähr 0.03.. Sekunden. Das ist normalerweise schlecht ne?

    ich kenne kein projekt, wo 0.03 sekunden ausführungszeit ein problem wäre.

    Wenn ich A.galerieid=B.galerieid=C.galerieid für die neue Query nehme, dann setze ich den PrimaryKey für alle drei Tabellen auf galerieid.

    damit setzt du gar nichts, sondern du joinst die tabellen über diese spalten. PK werden einmal beim erstellen der tabellen festgelegt und ändern sich (im idealfall) nicht mehr.

    • Wäre es von der Perfomance eher schlecht, bzw. überhaupt sinnvoll, wenn ich für die Tabelle präfix_kommentare 2 Primary Keys setze?

    erstens kannst du keine zwei PK für eine tabelle haben. es gibt pro tabelle immer nur einen. welcher das ist, dafür gibt es in jedem rdbms spezielle anweisung, um ihn zu setzen. und zweitens vermute ich mal, du hast zwei schlüssel in der tabelle, die beide eindeutig und hoffentlich auch not null sind.

    Nun meine Frage. Wenn nun ab und zu mal ein paar Zeilen von der Geo_Tabelle gelöscht werden (aus was für einem Grund auch immer) und neue Zeilen eingefügt werden mit fortlaufender ID, wäre dann ein Index besser oder ein Primary Key?

    eine spalte, die als PK deklariert ist (könnnen auch mehrere spalten sein), dafür setzt das dbms automatisch einen index, um genauer zu sein, sogar einen unique index. damit wird die eindeutigkeit des PK sicher gestellt. zusätzlich wird der Constraint not null gesetzt. PK sollte man immer für einen künstlichen schlüssel der tabelle verwenden.

    Ich habe irgendwo mal gelesen, dass es nicht gut sei, wenn man Zeilen löscht, wenn ein Index gesetzt ist.

    das löschen, einfügen und auch das updaten ist für den index sicherlich arbeit und nicht gerade förderlich. aber deswegen kann ich ja nicht einen datensatz behalten, den ich eigentlich löschen will. das ist aufgabe des dbms, dass mit dem index wieder hinzubekommen. falls es zuviele DML operatione gab, kann man einen index auch löschen oder und neu erstellen, bzw. on the fly neu generieren lassen, falls sich die datenbank im 24/7 (dauereinsatz) betrieb befindet.

    Ilja

    1. Hi Ilja, mein Retter ist wieder Anwesend ;)

      welches dbms und welche version ? beispieldaten angeben, sowohl inhalte der tabellen als auch das gewünschte result.

      mysql 4.1.10

      Von der dritten Tabelle, die präfix_kommentare heißt, brauche ich den count(*), wieviele Kommentare (Zeilen) von "where C.userid=1" in der Spalte Userid vorhanden sind.

      wie du diesen COUNT einbaust, ist abhängig von deinem dbms und der version. deswegen ist es immer wichtig, diesen zu kennen. desweiteren ist es interessant zu wissen, wo die selektion C.userid=1 stattfinden soll, sprich ob sie sich auf die ganze query auswirken soll oder nur auf den count. deswegen sind beispiele so wichtig, weil sie meistens für uns mehr aussagen als erklärungen.

      Es sollte sich nicht auf die Query ausirken. Zu der vorhandenen Query soll er einfach noch von der dritten Tabelle die Summe der Datensätze ermitteln, die im Where-Klausel mit wehre userid=1 angegeben ist. Das "C" habe ich stelltvertretend für die dritte Tabelle eingefügt. Dürfte schon richtig sein ne?

      Wenn man die obere Query abfrage, braucht er ungefähr 0.03.. Sekunden. Das ist normalerweise schlecht ne?

      ich kenne kein projekt, wo 0.03 sekunden ausführungszeit ein problem wäre.

      Das ist beruhigend ;)

      damit setzt du gar nichts, sondern du joinst die tabellen über diese spalten. PK werden einmal beim erstellen der tabellen festgelegt und ändern sich (im idealfall) nicht mehr.

      In der Tabelle präfix_kommentare ist der PK auf kommentarid. Hatte mir überlegt, ob ich den auf galerieid setzen soll oder auf kommentarid, deshalb lautete meine Frage, ob ich zwei PK's setzen kann,da man die Tabelle öfters mit galerieid und kommentarid anspricht.
      Ich arbeite mich mal die Tage in ganzen verschiedenen Schlüsseln einer Tabelle ein, damit ich das Ansprechverhalten optimiere.

      Grüße ;)
      undso

      1. yo,

        mysql 4.1.10

        das ist gut, damit kann dein dbms unterabfragen.

        Von der dritten Tabelle, die präfix_kommentare heißt, brauche ich den count(*), wieviele Kommentare (Zeilen) von "where C.userid=1" in der Spalte Userid vorhanden sind.

        das baust du komplett als unterabfragen in die SELECT klausel ein, da sie unabhängig ist.

        select A.kategorie, A.name, A.beschreibung, A.themen, A.antworten, MAX(B.thumbname),
        (SELECT COUNT(*) FROM präfix_kommentare WHERE userid=1) AS Anzahl
        from präfix_galerie AS A
        INNER JOIN präfix_galeriebilder AS B on A.kategorie=B.kategorie
        GROUP BY A.kategorie, A.name, A.beschreibung, A.themen, A.antworten
        ;

        es kann gut sein, dass eine fehlermeldung kommt, bei oracle wäre es meiner meinung so. dann musst du die unterabfrage noch aggregieren.

        select A.kategorie, A.name, A.beschreibung, A.themen, A.antworten, MAX(B.thumbname),
        MAX((SELECT COUNT(*) FROM präfix_kommentare WHERE userid=1)) AS Anzahl
        from präfix_galerie AS A
        INNER JOIN präfix_galeriebilder AS B on A.kategorie=B.kategorie
        GROUP BY A.kategorie, A.name, A.beschreibung, A.themen, A.antworten
        ;

        In der Tabelle präfix_kommentare ist der PK auf kommentarid. Hatte mir überlegt, ob ich den auf galerieid setzen soll oder auf kommentarid, deshalb lautete meine Frage, ob ich zwei PK's setzen kann,da man die Tabelle öfters mit galerieid und kommentarid anspricht.

        kommentarid scheint mir der richtige PK zu sein. galerieid hört sich nach einem Fremdschlüssel an und der kann dann mehrfach mit dem gleichen wert in der tabelle vorkommen, ansonsten wäre es ja eine 1:1  Beziehung.

        Man darf PK und schlüssel nicht miteinander verwechseln. selbst wenn es eine weitere spalte innerhalb einer tabelle gibt, die eindeutige werte hat und nicht null ist, selbst dann ist das kein zweiter PK, sondern eine ganz normale spalte. Oftmals wird sie auch alternatekey genannt. und sicherlich kann man darauf auch einen unique index legen, dass macht die spalte aber immer noch nicht zu einem weiteren PK. den kann es nur einmal in der tabelle geben.

        Ilja

        1. yo,

          mysql 4.1.10

          das ist gut, damit kann dein dbms unterabfragen.

          Hi,

          select A.kategorie, A.name, A.beschreibung, A.themen, A.antworten, MAX(B.thumbname),
          (SELECT COUNT(*) FROM präfix_kommentare WHERE userid=1) AS Anzahl
          from präfix_galerie AS A
          INNER JOIN präfix_galeriebilder AS B on A.kategorie=B.kategorie
          GROUP BY A.kategorie, A.name, A.beschreibung, A.themen, A.antworten
          ;

          es kann gut sein, dass eine fehlermeldung kommt, bei oracle wäre es meiner meinung so. dann musst du die unterabfrage noch aggregieren.

          select A.kategorie, A.name, A.beschreibung, A.themen, A.antworten, MAX(B.thumbname),
          MAX((SELECT COUNT(*) FROM präfix_kommentare WHERE userid=1)) AS Anzahl
          from präfix_galerie AS A
          INNER JOIN präfix_galeriebilder AS B on A.kategorie=B.kategorie
          GROUP BY A.kategorie, A.name, A.beschreibung, A.themen, A.antworten
          ;

          super, vielen Dank, werde ich gleich ausprobieren. Auf dich ist Verlass ;)

          Wie würde eigentlich die Query aussehen, wenn man das nicht mit einer Unterabfrage machen will? Also die drei Tabellen verbinden, damit ich das gleich lerne.

          Grüße ;)

          1. yo,

            Wie würde eigentlich die Query aussehen, wenn man das nicht mit einer Unterabfrage machen will? Also die drei Tabellen verbinden, damit ich das gleich lerne.

            schwieriger und daher meiner meinung nach der falsche ansatz ;-)

            Ilja

            1. Hi,

              schwieriger und daher meiner meinung nach der falsche ansatz ;-)

              Jep hast schon recht, aber was mir gerade einfällt:

              select A.kategorie, A.name, A.beschreibung, A.themen, A.antworten, MAX(B.thumbname),
              (SELECT COUNT(*) FROM präfix_kommentare WHERE userid=1) AS Anzahl
              from präfix_galerie AS A
              INNER JOIN präfix_galeriebilder AS B on A.kategorie=B.kategorie
              GROUP BY A.kategorie, A.name, A.beschreibung, A.themen, A.antworten
              ;

              Die "oberabfrage" (wenn das der richtige Begriff ist) liefert ja mehrere Ergebnisse/Zeilen.
              Im allen Zeilen des Ergebnissed steht dann in der letzten Spalte der count ne?

              Die obere Query nutze ich in einem Suchformurlar. Im Suchformular kann man dann den Usernamen eingeben, und schauen, ob eine Galerie vorhanden ist, wo der User ein Kommentar von sich hat. Als Ergebnis kommt dann die Galerie mit dem Count, wieviele Kommentare er in der Galerie hat. Was mir da in der Query auffällt, dass ich im wehere-clause der "Oberabfrage" where userid=1 für die dritte Tabelle "präfix_kommenare" brauche.

              Ich muss mir das mal morgen genaue reinziehen. bin gerade vielleicht nur verpeilt ;)

              Grüße