Bobby: PHP Doppelte Spaltennamen bei JOIN in MySQL

Moin

mag sich nach ner Newbie-Frage anhören. ist auch nur interesse halber

ich habe 2 Tabellen

user
id | name | usergroup

usergroup
id | name

So nun les ich das so aus (ich weiß, das gänge auch mit nem Kreuzprodukt, soll nur exemplarisch sein):

SELECT user.*, usergroup.* FROM user LEFT JOIN usergroup ON (user.usergroup = usergroup.id)

So ergebnis ist ein Datensatz mit folgenden Feldern: id, name, usergroup, id, name

Das ganze frage ich mit PDO ab und speicher dies über die Option PDO::FETCH_OBJ in ein Objekt. Nun wird aber nur der Name der Usergroup gespeichert. Gibt es eine Möglichkeit AUSSER ALIAS hier an den Bezeichner udn Werte beider Spalten zu kommen? (wie in der MySQL-Oberfläche)

Gruß Bobby

--
-> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
### Henry L. Mencken ###
-> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
### Viktor Frankl ###
ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
  1. Tach!

    Das ganze frage ich mit PDO ab und speicher dies über die Option PDO::FETCH_OBJ in ein Objekt. Nun wird aber nur der Name der Usergroup gespeichert. Gibt es eine Möglichkeit AUSSER ALIAS hier an den Bezeichner udn Werte beider Spalten zu kommen? (wie in der MySQL-Oberfläche)

    Nur über Spaltennummern. Metadaten zu den Spalten könnten auch noch die Namen hervorbringen. Aber dass PDO dir die Objekte anlegt, wirst du damit nicht hinbekommen.

    dedlfix.

    1. Moin

      Das ganze frage ich mit PDO ab und speicher dies über die Option PDO::FETCH_OBJ in ein Objekt. Nun wird aber nur der Name der Usergroup gespeichert. Gibt es eine Möglichkeit AUSSER ALIAS hier an den Bezeichner udn Werte beider Spalten zu kommen? (wie in der MySQL-Oberfläche)

      Nur über Spaltennummern. Metadaten zu den Spalten könnten auch noch die Namen hervorbringen. Aber dass PDO dir die Objekte anlegt, wirst du damit nicht hinbekommen.

      Ich hatte an etwas ähnliches gedacht wie: $obj->user->name und $obj->usergroup->name. Sowas scheint aber leider nicht möglich. Oder doch?

      Gruß Bobby

      --
      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
      ### Henry L. Mencken ###
      -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
      ### Viktor Frankl ###
      ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
      1. Tach!

        Ich hatte an etwas ähnliches gedacht wie: $obj->user->name und $obj->usergroup->name. Sowas scheint aber leider nicht möglich. Oder doch?

        Das ist nicht seitens PHP/MySQL möglich (aber du kannst dir das selbst so strukturieren). Um das erreichen zu können, müsste jeder Wert eindeutig einer Tabelle zugeordnet werden können. (Du kannst ja mal schauen, ob sowas in den Metadaten zu den Ergebnisfeldern zu erkennen ist.) Was aber macht man mit berechneten Ausdrücken? Welchen Pseudo-Tabellennamen bekommen diese vorangestellt?

        Du kannst dein Ziel erreichen, wenn du dir einen ORM nimmst, der für dich die Querys zusammenstellt und die Antworten objektorientiert liefert. Aber mit purem PHP/MySQL bekommst du es nicht ohne eigenen Aufwand hin.

        dedlfix.

        1. Moin

          Das ist nicht seitens PHP/MySQL möglich (aber du kannst dir das selbst so strukturieren). Um das erreichen zu können, müsste jeder Wert eindeutig einer Tabelle zugeordnet werden können. (Du kannst ja mal schauen, ob sowas in den Metadaten zu den Ergebnisfeldern zu erkennen ist.) Was aber macht man mit berechneten Ausdrücken? Welchen Pseudo-Tabellennamen bekommen diese vorangestellt?

          ok... Frage beantwortet...

          Gruß Bobby

          --
          -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
          ### Henry L. Mencken ###
          -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
          ### Viktor Frankl ###
          ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
  2. Moin
    [..] Gibt es eine Möglichkeit AUSSER ALIAS hier an den Bezeichner udn Werte beider Spalten zu kommen? (wie in der MySQL-Oberfläche)

    Warum willst Du denn den Alias'n nicht sinnvoll einsetzen? Dafür sind die doch da, also Dein Anliegen ist mir unverständlich. Zumal damit bei etwaigen Änderungen im DB-Design nix am Code gemacht werden muss. Und mit den richtigen Alias'n könnte eine Ergebnismenge ohne weiteren Code die Platzhalter für Templates zum Leben erwecken.

    MfG

    1. Moin

      [..] Gibt es eine Möglichkeit AUSSER ALIAS hier an den Bezeichner udn Werte beider Spalten zu kommen? (wie in der MySQL-Oberfläche)

      Warum willst Du denn den Alias'n nicht sinnvoll einsetzen? Dafür sind die doch da, also Dein Anliegen ist mir unverständlich. Zumal damit bei etwaigen Änderungen im DB-Design nix am Code gemacht werden muss. Und mit den richtigen Alias'n könnte eine Ergebnismenge ohne weiteren Code die Platzhalter für Templates zum Leben erwecken.

      ich möchte alles ein bisschen automatisieren. da wäre es schön wenn irgend so was rauskommt: $obj->user->name oder $obj->usergroup->name

      Das ist dann einfacher für mich. Aber wie es schein, gibt es eine solche Möglichkeit nicht. Schade eigentlich. würde vieles erleichtern.

      Gruß Bobby

      --
      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
      ### Henry L. Mencken ###
      -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
      ### Viktor Frankl ###
      ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
      1. moin,

        ich möchte alles ein bisschen automatisieren. da wäre es schön wenn irgend so was rauskommt: $obj->user->name oder $obj->usergroup->name

        Genau dafür gibt es ja den alias (auch im Plural). Gerade bei joins ist der alias so wichtig, weil bei einem select * die resultierenden Feldnamen nicht eindeutig sind.

        Am besten kannst Du Dich mit joins vertraut machen, wenn Du eine Tabelle mit sich selbst joinst, nehmen wir mal an, die Tabelle 'public' hat die Felder 'ent', 'att', 'val'. Jetz joinen wir mal die Tabelle mit sich selbst, schon allein dafür müssen wir einen alias auf den Tabellen-Namen setzen, sagen wir, a und b:

          
        select  
        *  
        from public a  
        join public b using(ent,att,val)  
        
        

        using(ent,att,val) heißt nun: Für den join müssen alle Felder übereinstimmen. Das Ergebnis entspricht der ursprünglichen Tabelle und doppelte Feldnamen treten nicht auf. Nun ein Feld aus der join-Bedingung raus, using(ent,att):

          
        select  
        *  
        from public a  
        join public b using(ent,att)  
        
        

        Jetzt sehen wir doppelte Feldnamen: ent att val val
        Weiter gehts mit using(ent), wir sehen im Result die Felder: ent att val att val

        Ergo: Sollen die Feldnamen eindeutig sein, müssen wir den Alias verwenden. Beispiel:

          
        select  
          
        a.ent as entity,  
        b.val as title,  
        c.val as short,  
        d.val as class  
          
        from public a  
        join public b using(ent,att)  
        join public c using(ent)  
        join public d using(ent)  
          
        where b.att='title' and c.att='short' and d.att='class'  
        
        

        Wir haben nun im Resultat die Spaltennamen: entity, title, short, class
        und praktisch heiß das: Genau dieselben Namen finden sich als Attribute in Deinen Objekten wieder. Vorausgesetzt, in Deiner Prgrammiersprache gibt es Methoden, die sowas entsprechend umsetzen (Perl ist hierzu sehr komfortabel).

        Installier Dir einen Query-Browser, lege eine Tabelle an und spiel mal ein bischen mit Self-joins. Beobachte auch die Anzahl der Zeilen, Du siehst sehr anschaulich, wie das Kreuzprodukt entsteht.

        Schöne Grüße.

        1. Moin

          Am besten kannst Du Dich mit joins vertraut machen, wenn Du eine Tabelle mit sich selbst joinst, nehmen wir mal an, die Tabelle 'public' hat die Felder 'ent', 'att', 'val'. Jetz joinen wir mal die Tabelle mit sich selbst, schon allein dafür müssen wir einen alias auf den Tabellen-Namen setzen, sagen wir, a und b:

          Also ich weiß schon wie Joins funktionieren und wie ein Alias funktioniert. Es ging mir echt darum ob es eine andere Möglichkeit gibt, dies ohne Alias zu automatisieren. Ich arbeite seit 10 Jahren mit MySQL und ich arbeite immer mit Alias... ;)

          trotzdem danke

          Gruß Bobby

          --
          -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
          ### Henry L. Mencken ###
          -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
          ### Viktor Frankl ###
          ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
          1. Moin

            Am besten kannst Du Dich mit joins vertraut machen, wenn Du eine Tabelle mit sich selbst joinst, nehmen wir mal an, die Tabelle 'public' hat die Felder 'ent', 'att', 'val'. Jetz joinen wir mal die Tabelle mit sich selbst, schon allein dafür müssen wir einen alias auf den Tabellen-Namen setzen, sagen wir, a und b:

            Also ich weiß schon wie Joins funktionieren und wie ein Alias funktioniert. Es ging mir echt darum ob es eine andere Möglichkeit gibt, dies ohne Alias zu automatisieren. Ich arbeite seit 10 Jahren mit MySQL und ich arbeite immer mit Alias... ;)

            Ooops ;)

            Automatisieren will jeder. Ich sehe auch zu, dass meine DB-Tabellen bzw. das Design Solcher, vom Code möglichst unabhängig wird. Daten-Abstraktion: Der Code wird unabhängig vom DB-Design und die Namen der Spalten (Feldnamen) spielen überhaupt keine Rolle mehr. Einzig der Code bestimmt die Datenstruktur und wo das gespeichert wird, ist dem Code egal (der Layer wird darüber hinaus austauschbar). ORM mal so betrachtet, vermittelt zwischen den in der DB vorliegenden Feldnamen und den Attributen der im Code verwendeten Datenobjekten. Im unten verlinkten Artikel gibt es dazu einen Abschnitt samt Performance-Betrachtung.

            Isses das, worauf Du hinauswillst und Dein Wunsch nach Automatisierung abzielt? Wenn ja, guck mal hier (sorry für Adsense), das Teil ist sehr praktisch und gar nicht so kompliziert wie mancher Leuter meinen mögen. Sehr vielen Anwendungen genügt das Entity/Attribute/Value-Datenmodell, kurz EAV und damit mache ich so ziemlich alles, neben persistenter Datenhaltung in Dateien oder Datenbanken auch Datenübertragungen mit zyklischen Strukturen (Webservices, Content-Management, Remote-DB-Management, Ajax).

            Schöne Grüße.

            1. Moin

              Automatisieren will jeder. Ich sehe auch zu, dass meine DB-Tabellen bzw. das Design Solcher, vom Code möglichst unabhängig wird. Daten-Abstraktion: Der Code wird unabhängig vom DB-Design und die Namen der Spalten (Feldnamen) spielen überhaupt keine Rolle mehr. Einzig der Code bestimmt die Datenstruktur und wo das gespeichert wird, ist dem Code egal (der Layer wird darüber hinaus austauschbar). ORM mal so betrachtet, vermittelt zwischen den in der DB vorliegenden Feldnamen und den Attributen der im Code verwendeten Datenobjekten. Im unten verlinkten Artikel gibt es dazu einen Abschnitt samt Performance-Betrachtung.

              Isses das, worauf Du hinauswillst und Dein Wunsch nach Automatisierung abzielt? Wenn ja, guck mal hier (sorry für Adsense), das Teil ist sehr praktisch und gar nicht so kompliziert wie mancher Leuter meinen mögen. Sehr vielen Anwendungen genügt das Entity/Attribute/Value-Datenmodell, kurz EAV und damit mache ich so ziemlich alles, neben persistenter Datenhaltung in Dateien oder Datenbanken auch Datenübertragungen mit zyklischen Strukturen (Webservices, Content-Management, Remote-DB-Management, Ajax).

              Danke. DAS ist mal ein Ansatz.

              Gruß Bobby

              --
              -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
              ### Henry L. Mencken ###
              -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
              ### Viktor Frankl ###
              ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
              1. Moin

                Danke. DAS ist mal ein Ansatz.

                Hab seit fünf Jahren meine Freude dran ;)

                Recht einfach wird eine Suchfunktion (sortiert nach Relevanz):

                  
                    my $q = qq(  
                        SELECT ent, match(val) against(?) as rel  
                        FROM $dal->{TABN} WHERE match(val) against(? in boolean mode)  
                        group by ent order by rel desc  
                    );  
                
                

                Hierzu brauchts einen FULLTEXT-Index auf das Feld val und die Collation ist anzupassen. Es kann eine WHERE-Klause geben, womit die Suche auf bestimmte "Quasi-Felder" eingegrenzt werden kann. Quasi-Feld z.B. att='subject' (Suche nur in Werten, die das Attribut 'subject' haben).

                Für eine stärkere Kopplung an die DB, z.B. wegen Datum/Zeit-Feldern kann diese "Hash-Tabelle" natürlich auch ganz normal als "Detail-Tabelle" an andere Tabellen gejoint werden.

                Andererseits können auch bestehende DB-Designs durch Anhängen einer EAV-Tabelle einfach erweitert werden ohne dass Felder hinzugefügt werden müssen.

                Schöne Grüße.