List, Abfragen aus 2 SQL Tabellen

  • N'abend,

    Ich muss / will auf einer Übersichtsseite Daten aus unterschiedlichen Tabellen abfragen. Wie gehe ich da am besten vor?

    Auf der Übersichtsseite hab ich zum einen Buttons, deren Anzahl und verlinkung von den erstellten Seiten ausgeht... Im ACP erstelle ich meine Seite

    Auf der gleichen Seite sollen mir die Daten ausgegeben werden, die der User zuvor eingegeben hat.


    Hier mein Template, um es verständlicher zu machen

    Ich müsste theoretisch in meiner Klasse 2x public $objectListClassName =, Praktisch geht es ja aber nicht, weil sich das sonst gegenseitig überschreibt. Irgendwelche Ideen?


    ~LG

  • Okay, habs jetzt glaub ich dank http://www.w3schools.com/sql/sql_join_left.asp dem so in etwa verstanden, aber ich weiß nicht wie mir das bei meinem Problem helfen soll.

    Die Phasen und die Applications haben ja so untereinander nix zu tun, also kann ich ja auch nicht sagen das phaseID = appID ist.


    Im ACP erstelle ich meine Phasen (gespeichert in der tabelle phase - gleichzeitig wird für jede erstelle Phase auf der Übersichtsseite ein Link erstellt, der zu dieser Phase verlinkt

    In der Phase kann ein Benutzer seine Infos o.ä. eingeben (gespeichert in der Tabelle applications). Auf der Übersichtsseite unter den Links wird in Kurzform ausgegeben, wann und für was er sich beworben hat.

  • Wenn die Daten aus den Tabellen in keinem Verhältnis zueinander stehen, wieso fragst du sie dann nicht nacheinander ab? Du hast ein List Objekt für die eine Tabelle und ein List Objekt für die andere Tabelle.

  • Du hast ja eine Tabelle phase und eine application. Entsprechend hast du vermutlich auch eine PhaseList Klasse und eine ApplicationList Klasse, welche jeweils von DatabaseObjectList erben. Du erstellst also, je nach dem wo du die jeweilige Liste oder beide Listen brauchst von der einen Klasse eine Instanz und von der anderen Klasse.

  • Mhmm... Ich glaube, ich komme um dieses Left Join nicht herum... Aber irgendwie blicke ich da noch nicht ganz so durch :/

    Die klasse, bzw das Left Join

    PHP
    /**
    	 * Initializes DatabaseObjectList instance.
    	 */
    	protected function initObjectList() {
    		parent::initObjectList();
    		$this->objectList->getConditionBuilder()->add('isActive = ?', array(1));
    		$this->objectList->sqlSelects = 'user_table.username, paid_subscription.title';
    		$this->objectList->sqlJoins = "LEFT JOIN wcf".WCF_N."_user user_table ON (user_table.userID = paid_subscription_user.userID)";
    		$this->objectList->sqlJoins .= " LEFT JOIN wcf".WCF_N."_paid_subscription paid_subscription ON (paid_subscription.subscriptionID = paid_subscription_user.subscriptionID)";
    	}

    Bezieht sich auf das im Template -> Richtig?

    Verstehe aber die Logik dahinter noch nicht so ganz wie da wo was ist...

    Wäre dankbar, wenn mir da jemand nen Schups in die richtige Richtung gibt.

  • Nein, Template und LEFT JOIN haben erst mal nichts miteinander zu tun. Du hast Daten in der Datenbank. Diese fragst du per SQL ab und hast sie dann entweder als Array(s) oder Objekt(e) in PHP. Was du nun mit diesen Daten machst ist völlig offen. Du kannst sie in einem Template ausgeben, aber das ist nicht zwingend notwendig.

    Ob das LEFT JOIN notwendig ist oder nicht, hängt davon ab, ob die zwei Tabellen beziehungsweise die darin enthaltenen Daten in einer Beziehung zueinander stehen. Beispielsweise gibt es die Tabelle wcf1_bbcode und wcf1_bbcode_attribute. Jedes Attribute ist genau einem BBCode zugeordert (die attribute-Tabelle hat eine Spalte bbcodeID, deren Wert das Attribute genau einem BBCode zuordnet) und jeder BBCode kann beliebig viele Attribute haben. Um BBCodes mit ihren Attributen zu selektieren, macht man also:

    SQL
    SELECT		*
    FROM		wcf1_bbcode_attribute attribute
    LEFT JOIN	wcf1_bbcode bbcode
    ON		(bbcode.bbcodeID = attribute.bbcodeID)

    Wir sagen hier: Nimm alle Zeilen aus der attribute-Tabelle und füge zu jeder Zeile noch die Daten des zugeordneten BBCodes aus der bbcode-Tabelle hinzu. Die Verknüpfung zwischen Attribut und BBCode passiert in der Zeile ON (bbcode.bbcodeID = attribute.bbcodeID).

    Du solltest dich vielleicht noch etwas mehr in die Thematik (My)SQL Datenbank und Datenbankabfragen einlesen. Beispielsweise hier http://www.mysqltutorial.org/basic-mysql-tutorial.aspx oder hier http://www.w3schools.com/sql/sql_intro.asp. Dort findest du auch Kapitel zum Thema JOINs.

    Du hast weiter oben etwas von Phasen und Applications geschrieben. Haben die Daten in diesen Tabellen eine Beziehung, beispielsweise jeder Eintrag in der Phase Tabelle ist genau einer Application zugeordnet und jeder Eintrag in der Application Tabelle kann mehrere Phase Einträge in der Phase Tabelle haben? Dann könnten JOINs das sein, was du willst. Da du allerdings, soweit ich das mitbekommen habe, noch am Lernen bist und die Entwicklung auch explizit machst, um unter anderem dazuzulernen, sollte am Ende der Code von dir nicht nur funktionieren, sondern du solltest auch genau verstehen was jede einzelne Zeile davon macht. Du hast den Code schließlich geschrieben.

  • In der Übersichtsseite haben beide Tabellen erstmal grundsätzlich nichts zu tun.
    Ich bin zwar noch nicht so weit, aber ich baue mir gedanklich erstmal alles im Kopf auf wie was funktionieren könnte, bzw was ich brauch um zum Ergebnis zu kommen.

    Wo ich diese Joins evtl. brauche, ist bei der Ausgabe der jeweiligen Bewerbung. Ich versuchs mal zu erklären.

    Im ACP erstelle ich meine Phase:


    (Bild sagt mehr wie 1000 Worte)

    Die Felder sind jeweils die Beschreibungen, was der Benutzer in das Textfeld eingeben muss. Bspw. Wie lautet dein YT Name?

    In der Ausgabe muss ich aber wissen, wie die Beschreibung zum jeweiligen Feld ist, weil was bringt es mir wenn nur der YTName da steht, ich aber nicht weiß was das Feld eigentlich verlangte.

    Also hab ich in der Ausgabe: Wie lautet dein YT Name? YTberYX

    Die Beschreibung steht in der Tabelle phase, der YT Name in der Tabelle application
    Die Verbindung denke ich bekomme ich hin, wenn ich als hidden field die Phase für die Tabelle application mitgebe. In der Tabelle phase steht die ebenfalls

  • Ist jede Zeile der Application Tabelle entsprechend genau einer Zeile in der Phase zugeordnet? Und wenn du eine Zeile aus der Application Tabelle anzeigen möchtest, brauchst du entsprechend den Inhalt der Zeile in der Phase Tabelle, welcher die Application zugeordnet ist? Dann ist das Arbeiten mit JOINs eine Möglichkeit das Ganze zu lösen.

  • Hat es einen speziellen Grund, dass du nicht mit Integer IDs arbeitest für die Referenzierung? Falls nicht, hat es sich etabliert, dass du in der Phase Tabelle eine Spalte phaseID hast, welche vom Typ Integer ist und ein AUTO_INCREMENT hat, sodass jeder Eintrag einen um eins höheren Wert hat. In der Application Tabelle hast du dann ebenfalls eine Spalte phaseID (ohne AUTO_INCREMENT) und dort trägst du die phaseID der Phase ein, zu welcher die Application gehört. Man kann das ganze auch mit Strings machen. Im Regelfall und auch in den meisten Fällen im WCF ist die Nutzung von Integer aber Standard.

    Nochmal etwas zu deiner Frage aus Beitrag 13: Das LEFT JOIN und das Template haben durchaus etwas miteinander zu tun, allerdings eher im konzeptionellen Sinne. Mit dem LEFT JOIN (bzw. einem JOIN allgemein) sorgst du dafür, dass zusätzliche Daten selektiert werden. Das wird an dieser Stelle gemacht, weil diese zusätzlichen Daten im Template angezeigt werden sollen oder für andere Zwecke benötigt werden. Der Punkt ist: Wie du an die Daten kommst, die im Template benötigt werden, legt nicht das Template fest.

    Um es am Beispiel der BBCodes und BBCode Attribute deutlich zu machen: Angenommen du möchtest einen BBCode (Name, Tag) und alle seine Attribute anzeigen, dann kann das über ein JOIN gelöst werden. Du könntest aber auch erst den BBCode mit einer Datenbankabfrage auslesen und im Anschluss in einer zweiten unabhängigen Datenbankabfrage die Attribute, welche dem BBCode zugeordnet sind. Das Template legt also nicht fest, wie du an die Daten kommen musst. Das Template legt nur fest, welche Daten in welchem Format es erwartet. Da du letztendlich sowohl das Template erstellst und die Daten abfragst, hast du entsprechend Spielraum.

  • Ich muss das nochmal hochholen. In meiner Auflistung aller Einträge funktioniert das mit dem Left Join

    Jedoch auf der Seite, wo nur das Eingegebene angezeigt werden soll, funktioniert es nicht...

    Was angezeigt wird ist... nichts. In meiner Übersicht ist anders, dass ich die Einträge in einer Schleife mit item=app ausgebe. Liegt es vielleicht daran?
    Jetzt in der Ausgabe brauche ich keine Schleife...

  • Du möchtest jetzt eine Application, also eine Zeile aus der Application Tabelle, ausgeben?

    Von was erbt die Page, aus welcher der PHP Code aus deinem Post stammt? Wo wird $this->app, welche du in der assignVariables an das Template übergibst, ein Wert zugewiesen?

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!