das hab ich auch schon probiert, allerdings ohne Erfolg...leider 😢
Suche mit 1-N Relation
es funktioniert 🙂
zwar etwas anders als geplant und vielleicht nicht so ganz im Sinne des Erfinders aber es tut...yipii
function main($content,$conf) {
$this->conf=$conf;
$this->pi_setPiVarDefaults();
$this->pi_loadLL();
$this->pi_USER_INT_obj=1; // Configuring so caching is not expected. This value means that no cHash params are ever set. We do this, because it's a USER_INT object!
$content =$this->pi_list_searchBox();
$content .= $this->piVars[sword]."<br />";
$sword = $this->piVars[sword];
if($sword != "") {
$res = $GLOBALS['TYPO3_DB']->sql(TYPO3_db, 'SELECT * FROM tx_table1, tx_table2 WHERE tx_table2.zip = '.$sword.' AND tx_table2.fieldmanager = tx_table1.uid');
while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
$content .= $row['name'].'<br />';
}
}
return $this->pi_wrapInBaseClass($content);
}
über Verbesserungsvorschläge freue ich mich natürlich auch weiterhin 😉
genau da lande ich auch immer, da mir diese mm-Beziehung von Typo3 völlig schleierhaft ist, vor allem wenn man die Beziehung viel einfacher in SQL formulieren kann.
Für einfache Abfragen geht das ja noch, aber bei komplexeren Joins etc. mach ich mir den SQL lieber selber.
@suitside - ist doch prima wenn es so funktioniert, der Code ist auch viel schlanker und übersichtlicher.
Ich empfehle Dir die extension ExtDevEval, da kannst Du am schnellsten den Syntax nachschauen ( oder forschen )
Also ich stehe vor dem gleichen Problem. Nur bin ich wahrscheinlich noch erfahrungsärmer was Datenbanken betrifft. Das kommt davon, wenn ein Designer die Arbeit eines DB-Menschen übernehmen muss :o(
In meinem Fall.
Tabelle 1 enthält allgemeine Infos wie Titel und andere Daten.
Tabelle 2 enthält die Postleitzahlen und den Ort.
Ich muss nun eine oder mehrere Postleitzahlen einem Datensatz aus Tabelle 1 zuordnen.
Ich habe also in Tabelle 1 diese Database Relation zu Tabelle 2 gemacht und kann im BE wunderbar die PLZ zuordnen. Aber weiter scheitert es an der Darstellung in der Liste und natürlich der Suche nach der PLZ. Will heißen, statt der PLZ wird nur eine UID ausgegeben.
Nun hab ich versucht Deinen Code zu portieren. Aber mir fehlt leider das Wissen und die Zeit, mich Tagelang mit PHP-Grundwissen herumzuschlagen.
Vielleicht kannst Du mir aber noch ein wenig behilflich sein??
Die Suche soll also anhand der PLZ eine Trefferliste der Datensätze aus Tabelle 1 ausgeben. Wenn ich dann einen Datensatz auswähle, dann soll’s weiter zur Singl-Ansicht gehen.
Im Moment stehe ich noch mächtig auf dem Schlauch. 🙁
Das hier ist mächtiger:
'SELECT FROM tx_table1 join tx_table2 on tx_table1.uid = tx_table2.fieldmanager WHERE tx_table2.zip = '.addslashes($sword);
ho ho ho 😉 wenn man weis damit umzugehen sicher.. Ich dümpele noch im Ansatz mit meinem obigen Problem.
Eine Frage: Gibt’s einen Schalter oder einen anderen Grund, warum ein debug nicht ausgegeben wird? Beispielsweise sollte "debug(array($query));" mir doch den kompletten String ausgeben. Es passiert aber rein gar nichts.
D.
'SELECT FROM tx_table1 join tx_table2 on tx_table1.uid = tx_table2.uid WHERE tx_table2.POSTLEITZAHL = '.addslashes($POSTLEITZAHL);
Kann ich überhaupt nix mit anfangen, weil mir das Konstrukt Drumherum fehlt, bzw. noch das aus dem Kickstarter Plugin ist. Das passt mit dem nicht zusammen oder? Ich wüsste nicht was ich rausschmeißen und hinzufügen muss.
Langsam bezweifele ich, dass ich das dieses Jahr noch hinbekomme. Kommt davon, wenn man jemandem einen Gefallen tun möchte und eigentlich zu wenig Ahnung hat den kompletten Durchblick zu finden. Ich beschäftige mich leider zu selten mit DB-Abfragen.
Eigentlich möchte ich "nur" über das Plugin eine PLZ suchen, die über die Database Relation mit nem Datensatz einer anderen Tabelle verknüpft ist – finden, und mit Klick auf diesen Treffer in der Singl-Ansicht dieses Datensatzes landen. So was bringt ja der Kickstarter schon fast mit, nur halt nicht über eine zweite Tabelle. Wenn doch nur schon Weihnachten währe 😢
Wenn Du das in Typo3 mit MM-Tabellen gemacht hast, dann könnte es so funktionieren:
'SELECT FROM tx_table1 JOIN tx_table_MM on tx_table1.uid = tx_table_MM.uid JOIN tx_table2 on tx_table_2.uid = tx_table_MM.pid WHERE tx_table2.POSTLEITZAHL = '.addslashes($POSTLEITZAHL);
Wenn Du das ohne Umhängetabelle gemacht hast, dann versuch mal das hier:
'SELECT FROM tx_table1 WHERE tx_table1.uid IN (SELECT MM FROM tx_table2) AND tx_table2.POSTLEITZAHL = '.addslashes($POSTLEITZAHL);
aha und den String dann in die Variable '$query' schreiben? Damit das Plugin den Standard überschreibt?
Der String sieht super aus und das funktioniert sicher auch. Aber wie "verheirate" ich das mit einem Plugin, dass mit dem Kickstarter erstellt wurde und bereits eine Liste ausgibt?
Auf alle Fälle danke ich Dir für Deine Mühe!
D.
aha und den String dann in die Variable '$query' schreiben? Damit das Plugin den Standard überschreibt?
ja
naja so einfach $query = ... in die Funktion klatschen ist nicht..
Hab die Version mit der mm Zusatztabelle der Einfachheit halber mal raus genommem und Deinen zweiten Code eingesetzt. Aber ich pack's sicher ganz falsch an... kapier nicht den Zusammenhang mit dem Standardcode im Plugin der die Tabelle aufbaut. Aber ich sehe mittlerweile auch schon den Wald vor lauter Bäumen nicht mehr 🙁
Hier das hab ich fabriziert ist mein Code
function listView($content, $conf) {
$myTable = 'tx_dfhsw_versorger'; // altuelle Tabelle
$query = $GLOBALS['TYPO3_DB'].'SELECT FROM tx_dfhsw_versorger WHERE tx_dfhsw_versorger.uid IN (SELECT MM FROM tx_dfhsw_plz) AND tx_dfhsw_plz.plz = '.addslashes($plz);
$this->conf = $conf;
// Setting the TypoScript passed to this function in $this->conf
$this->pi_setPiVarDefaults();
$this->pi_loadLL();
// Loading the LOCAL_LANG values
$this->pi_USER_INT_obj = 1; // Configuring so caching is not expected.
$lConf = $this->conf['listView.']; // Local settings for the listView function
if ($this->piVars['showUid']) {
// If a single element should be displayed:
$this->internal['currentTable'] = $myTable;
$this->internal['currentRow'] = $this->pi_getRecord($myTable, $this->piVars['showUid']);
$content = $this->singleView($content, $conf);
return $content;
} else {
if (!isset($this->piVars['pointer'])) $this->piVars['pointer'] = 0;
if (!isset($this->piVars['mode'])) $this->piVars['mode'] = 1;
// Initializing the query parameters:
list($this->internal['orderBy'], $this->internal['descFlag']) = explode(':', $this->piVars['sort']);
$this->internal['results_at_a_time'] = t3lib_div::intInRange($lConf['results_at_a_time'], 0, 1000, 3); // Number of results to show in a listing.
$this->internal['maxPages'] = t3lib_div::intInRange($lConf['maxPages'], 0, 1000, 2);
// The maximum number of "pages" in the browse-box: "Page 1", 'Page 2', etc.
$this->internal['searchFieldList'] = 'gv_name,gv_plz,gv_ort,kd_plz';
$this->internal['orderByList'] = 'gv_name,gv_ort,kd_plz';
// Get number of records:
$res = $this->pi_exec_query($myTable, 1);
list($this->internal['res_count']) = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
// Make listing query, pass query to SQL database:
$res = $this->pi_exec_query($myTable);
$this->internal['currentTable'] = $myTable;
// Put the whole list together:
$fullTable = ''; // Clear var;
// Adds the whole list table
$fullTable .= $this->pi_list_makelist($res);
// Adds the search box:
$fullTable .= $this->pi_list_searchBox();
// Adds the result browser:
$fullTable .= $this->pi_list_browseresults();
// Returns the content from the plugin.
return $fullTable;
}
}
Wenn Du nochmal dazu was sagen möchtest, dann freue ich mich. Wenn nicht, dann muss ich andere Wege suchen, dass ganze fängt nämlich langsam mächtig an zu nerven.. aber habs leider versprochen 🙁
Kleiner Nachtrag,
Kaspers Video Funktioniert schon. Hab ich gerade festgestellt! Allerdings wird dieser ausgetauschte Wert nicht mit in die Suche einbezogen, da 'searchFieldList' ja nur den Ursprungswert, also die UID sieht.
Na ganz toll und sobald mehrere Datensätze zugeordnet sind, wird auch nix mehr ausgegeben.. Da muss dann wohl sowas wie ne schleife mit rein. Aber es geht mir ja eigentlich nicht um die Ausgabe der PLZ sondern das der Datensatz gezeigt wird, wenn eine PLZ über die Suche gefunden wird.
Naja, ich habe ja angefangen mit MÄCHTIGEN SQL-Queries. Hab' auch keine Lust Dich auf eine falsche Fährte zu locken. Den Unterschied zwischen Where und Join kann man ungefähr so beschreiben:
Vor Ergebnis her sind beide Abfrage-Alternativen gleichwertig, aber die SQL92-Fassung ist für Dritte besser lesbar:
* Die beteiligten Tabellen werden über die JOIN-Anweisung bereits in der richtigen Reihenfolge benannt, wobei die Abhängigkeiten über die ON-Klausel direkt der JOIN-Anweisung zugeordnet werden.
* Die WHERE-Klausel enthält nur noch die Einschränkungen der Ergebnismenge, aber nicht mehr zusätzlich die Beziehungen der Tabellen untereinander.
Außerdem kann es nur bei der alten SQL89-Schreibweise aus Versehen zu einem kartesischen Produkt kommen, wenn im WHERE-Abschnitt eine Beziehung vergessen wird. Bei der SQL 92-Syntax meldet sich der SQL Server beim Ausführen einer unvollständigen SELECT-Anweisung sofort mit einem Veto zu Wort, da die im Hintergrund ablaufende Syntaxprüfung den Fehler sofort entdeckt. Wenn das kartesische Produkt tatsächlich benötigt wird, muss dies in der SQL92-Fassung explizit über CROSS JOIN angefordert werden.
Hi nochmal.
Ich hab noch immer nicht hinbekommen, dass die PLZ der zweiten Tabelle mit in die Suche einbezogen wird.
Was ist denn an diesem String falsch?
$query = 'SELECT * FROM tx_dfhsw_versorger JOIN tx_dfhsw_versorger_kd_plz_mm on tx_dfhsw_versorger.uid = tx_dfhsw_versorger_kd_plz_MM.uid JOIN tx_dfhsw_plz on tx_dfhsw_plz.uid = tx_dfhsw_versorger_kd_plz_MM.pid WHERE tx_dfhsw_plz.PLZ = '.addslashes($PLZ);
Ich bekomme die debug-Meldung:
aller t3lib_DB::sql
ERROR Fehler in der Syntax bei '' in Zeile 1.
lastBuiltQuery SELECT * FROM tx_dfhsw_versorger JOIN tx_dfhsw_versorger_kd_plz_mm on tx_dfhsw_versorger.uid = tx_dfhsw_versorger_kd_plz_MM.uid JOIN tx_dfhsw_plz on tx_dfhsw_plz.uid = tx_dfhsw_versorger_kd_plz_MM.pid WHERE tx_dfhsw_plz.PLZ =
debug_backtrace ux_tslib_fe->intincscript // ux_ux_tslib_cobj->user // ux_ux_tslib_cobj->calluserfunction // call_user_method // tx_dfhsw_pi1->main // tx_dfhsw_pi1->listview // t3lib_db->sql // t3lib_db->debug
Mir ist gerade aufgefallen, dass Du wegen dieser Frage schon 3 Threads aufgemacht hast.
#71690
#71611
und diesen hier.
Das macht man nicht.
Und man rennt auch nicht hinter jedem her der eine potenzielle Antwort hat. Just2b wollte Dir schon helfen. Dann machst Du einfach noch ein Thread auf. Kannst nicht auf eine Antwort warten, bzw. kriegst auch keine. Und in einem anderen Thread fängst Du an mit mir darüber zu diskutieren. Das macht man auch nicht.
Nun nochmal zu Deiner Frage: Das ist Standart-Sql. Mir fällt da nichts auf.
Siehe: http://www.spotlight-wissen.de/lisp/pages/messages/asql-1108551613-3649
@Tetramatrix Ach kannst Du bitte Deinen Oberlehrer nicht so raushängen lassen??! Du magst ja im Ansatz Recht haben aber 1. habe ich nicht 3 Threads mit dem gleichen Thema aufgemacht und 2. mache ich nur das in einem Forum, wozu ein Forum auch da ist, Fragen und nachhaken und wenns sein muss auch öfter. Denn ich hab festgestellt, so mancher Thread landet mit 0 Antworten in der Versenkung, wenn man hier nicht nachhakt. Wenn keiner Probleme hätte, dann wäre das hier wohl nicht notwendig oder? Ein Forum ist nicht zum Schulterklopfen da.
Den ersten Thread habe ich nach zunächst erfolgloser Suche zum Thema aufgemacht. Der zweite galt einem ganz anderen Problem, ergab sich nur im Verlauf, dass ich auch da (sorry) die Frage angeschlossen hatte. Den dritten Thread habe ich nicht aufgemacht, sondern zu diesem Thema zufällig und erst später gefunden.
Also bitte, was soll diese Wichtigtuerei! Du magst ja sehr fähig sein, hast Deine Stärken da, wo ich meine woanders habe. Hinter rennen tu ich aber niemanden, bin ich schon längst keine 30 mehr 😉
Aber das soll jetzt keine Rechtfertigung sein! Ich werde wahrscheinlich noch öfter, vielleicht intensiver nachhaken wenns sein muss. Es steht ja jedem frei zu Antworten. Und es mach ja auch immer der Ton die Musik.
Trotzdem Danke ich für jede Antwort.
Frohe Feiertage, D.
Ich habe es nun endlich hinbekommen.
Meine Liste wird durch eine eigene from_table und where_clause ordendlich durchsucht. Jetzt kommen die Schönheitsoperationen. Z.B. möchte ich nicht, das bei Aufruf des Plugin alle Datensätze angezeigt werden. Treffer sollen nur bei Ünereinstimmung ausgegeben werden. Weiter soll ein Hinweistext erscheinen, wenn KEIN Treffer gefunden wurde. Auch funktioniert die Result-Anzeige so nicht. Weiss jemand Rat?
Hier mal mein Code. Vielleicht hilfts auch anderen.
D.
function listView($content, $conf) {
$this->conf = $conf;
$this->pi_setPiVarDefaults();
$this->pi_loadLL();
$this->pi_USER_INT_obj = 1;
$lConf = $this->conf['listView.'];
if ($this->piVars['showUid']) {
$this->internal['currentTable'] = 'tx_dfhsw_versorger';
$this->internal['currentRow'] = $this->pi_getRecord('tx_dfhsw_versorger', $this->piVars['showUid']);
$content = $this->singleView($content, $conf);
return $content;
} else {
if (!isset($this->piVars['pointer'])) $this->piVars['pointer'] = 0;
if (!isset($this->piVars['mode'])) $this->piVars['mode'] = 1;
list($this->internal['orderBy'], $this->internal['descFlag']) = explode(':', $this->piVars['sort']);
# NEU #############################################################################
$SuchText = $this->piVars['sword'];
$select_fields = 'tx_dfhsw_versorger.*';
$from_table = '(tx_dfhsw_versorger INNER JOIN tx_dfhsw_versorger_kd_plz_mm ON tx_dfhsw_versorger.uid = tx_dfhsw_versorger_kd_plz_mm.uid_local)
INNER JOIN tx_dfhsw_plz ON tx_dfhsw_versorger_kd_plz_mm.uid_foreign = tx_dfhsw_plz.uid';
$where_clause = "(tx_dfhsw_plz.plz Like '%".$SuchText."%'".$this->cObj->enableFields('tx_dfhsw_versorger').')';
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = ''.$orderBy = ''.$limit = '');
##############################################################################
$this->internal['results_at_a_time'] = t3lib_div::intInRange($lConf['results_at_a_time'], 0, 1000, 3);
$this->internal['maxPages'] = t3lib_div::intInRange($lConf['maxPages'], 0, 1000, 2);
$fullTable = '';
$fullTable .= $this->pi_list_searchBox();
$fullTable .= $this->pi_list_makelist($res);
$fullTable .= $this->pi_list_browseresults(); // geht nicht :(
return $fullTable;
}
}