Zum Inhalt springen

UNION verwenden bei ListView

Erstellt am 22. Februar 2008 · 8 Antworten · letzte Antwort am 24. Februar 2008

Tags: PHP, Datenbank, Frage

Booley ·

Hallo zusammen,

ich kämpfe immer noch mit meiner ersten Extention. Jetzt habe ich folgendes Problem:

Ich möchte gerne dieses SQL als Datengeber verwenden:

SELECT * FROM tx_dgsimmo_obj 
where uid_stadtteil = 3

union

SELECT * FROM tx_dgsimmo_obj 
where tx_dgsimmo_obj.uid_stadtteil in
  (select uid from tx_dgsimmo_stadtteil
   where uid_stadtteilreg = 
    (select uid_stadtteilreg from tx_dgsimmo_stadtteil
     where uid = 3
    )
  )

Sinn und Zweck ist folgedner:
(ich lasse zum besseren Verständnis jetzt mal den Ext-Key bei den Tabellenbezeichnungen weg)

Jedem Objekt ist ein Stadtteil zugeordnet
Tabelle: obj
Feld: uid_stadtteil

Jedem Stadtteil ist eine Region zugeordnet:
Tabelle: stadtteil
Feld: uid_stadtteilreg

Ich habe in meiner listView ein DropDown-Feld eingefügt, welches mir alle Stadtteile ausgibt. Wenn ich hier eine Auswahl treffe, sollen

- zuerst alle Objekte aus dem gewählten Stadtteil ausgegeben werden
- und anschließend alle weiteren Objekte aus der Region ausgegeben werden, zu welcher der Stadtteil gehört.

Das obige SQL verrichtet im Prinzip seinen Dienst so, wie ich es gerne hätte.

Mein Problem ist, dass ich nicht weiß, wie ich das "pi_exec_query" bestücken muss, damit ich das SQL mit der UNION-Anweisung verwenden kann. Also habe ich es ein wenig ausgetrickst:

Die Doku sagt:

tslib_pibase.pi_exec_query  	(
          	$table,
		$count = 0,
		$addWhere = '',
		$mm_cat = '',
		$groupBy = '',
		$orderBy = '',
		$query = ''
)

Zum "addWhere" steht folgendes:
"Additional WHERE clauses (should be starting with " AND ....")"

Die Parameter sind hier komplett erklärt: http://typo3.org/fileadmin/typo3api-4.0.0/df/d32/classtslib__pibase.html#71db8cffd4bc879c99106247adb997cd

Also habe ich folgendes gemacht:

$where.=' and uid_stadtteil ='.$stadtteil.'
          union 
          SELECT * FROM tx_dgsimmo_obj 
          where tx_dgsimmo_obj.uid_stadtteil in
            (select uid from tx_dgsimmo_stadtteil
             where uid_stadtteilreg = 
               (select uid_stadtteilreg from tx_dgsimmo_stadtteil
                where uid = '.$stadtteil.'
               )
             )
         ';

$res = $this->pi_exec_query('tx_dgsimmo_obj',0,$where);

Das funktioniert auch zunächst wunderbar. Wenn ich allerdins die Ergebnisliste durch einen Klick auf eine Überschrift umsortiere, knallt es. Es ist naheliegend, dass die Syntax zerschossen wird.

Außerdem geht mir durch das UNION-SQL die Einschränkung auf die Datensätze der ausgewählten Seiten im PLugIn verloren, was man aber sichlich noch in den Griff bekommt. Für die PID's wird es ja vermutlich eine Variable geben.

Lange Rede, kurzer Sinn:
Es scheint nicht die optimale Lösung zu sein und ich weiß nicht mehr weiter...

Wie muss ich pi_exec_query korrekt bestücken? Oder kann ich eine andere Funktion nutzen?

Wer kann helfen?

Gruß
Booley

PS: Ich hoffe, dass irgendjemand bis hier durchgehalten hat und auch noch verstanden hat, was ich da verzapft habe...
#giggle#

jenses ·

Für solche avancierten Queries kannst du die Funktionen aus der class.tslib_pibase.php vergessen, die sind nur für Standard-"Klicke-3-mal-im-Kickstarter-und-fertig-ist-die"-Extensions zu gebrauchen.
Benutze stattdessen die Funktionen der class.t3lib_db.php,
um FE-Klick-Sortierung etc. mußt du dich dann natürlich selber kümmern...

laser ·

Ich hab jetzt nicht alles gelesen, aber dein Problem ist das Query und das ausgeben der Datensätze weil du mehrere Tabellen ansprichst?

Schonmal was von JOIN gehört?

Du kannst auch über ...

$GLOBALS['TYPO3_DB']->sql(TYPO3_db,"SELECT ...");

... deine Queries machen.

Booley ·

Hallo zusammen,

vielen Dank erst einmal für die Antworten und sorry meine späte Antwort darauf, aber ich war heute den ganzen Tag offline unterwegs.

@jenses:
Die Funktionen "class.t3lib_db.php" habe ich bis jetzt noch nicht benutzt. Ich habe jetzt mal in die Doku geschaut (soll ja helfen... 😃 ). Ich finde da jedoch keine wirklich passende Funktion für mein SQL. Also mit Subqueries und UNION.

Oder meinst du, es würde mir helfen, wenn ich mit "exec_SELECTquery" arbeite? Ich sehe da allerdings keine wirklichen Unterschied zu "pi_exec_query".

Ansonsten wäre da noch die Funktion "t3lib_DB.sql_query", welche ja anscheinend ohne Parameten arbeitet. Sollte das die Funktion meiner Wahl sein?

Wärst du so freundlich, und könntest mir da noch einmal auf die Sprünge helfen?

@steffenk:
Ja, ich benutze Subqueries, aber halt auch Union

SELECT * FROM tx_dgsimmo_obj
where uid_stadtteil = 3

union

SELECT * FROM tx_dgsimmo_obj
...

Ich vermute mal, dass ich bei reinen Subqueries kein Problem hätte, da das komplette zweite SQL ja in der WHERE Bedingung eingebettet ist. Dann sollten auch die Standrad-Funktionen zum Sortieren usw. noch funktioklappern. Oder habe ich da einen Denkfehler? Dann bitte korrigieren.

@laser:
Eigentlich ist nicht das Query mein eigentliches Problem. Mein SQL läuft ja im Prinzip schon, wenn man mal von der angesprochenen Unschönheit absieht, dass die Startpunkte aus dem PlugIn noch nicht integriert sind.

Von JOIN habe ich schon gehört. Wenn du ein bessere Idee hast, wie man das SQL-Statement umsetzen kann, dann immer her damit. Ich sehe aber im Moment keine Möglichkeit, das UNION zu vermeiden. Aber auch da lasse ich mich gerne eines Besseren belehren.

Verständnisfrage:
Spreche ich mit

$GLOBALS['TYPO3_DB']->sql(TYPO3_db,"SELECT ...");

nicht die Funktionen aus "class.t3lib_db.php" an?

@all: Da ich mich ja anscheinend von den gewohnten Pfaden verabschieden muss, hier schon mal die vorprogrammierte Folgefrage:
Gibt es ein Array, welches die PID der Ausgangspunkte enthält, welche man bei Plug-Ins auswählen kann? Und in welche Doku hätte ich gucken müssen, um es selbst heraus zu bekommen?

steffenk ·

bei den komplexen queries bzw. UNION führt kein Weg an
$GLOBALS['TYPO3_DB']->sql_query($sql);

vorbei. Der nachteil ist halt das es nicht mehr DBAL-kompatibel ist.

Zu den pids, dazu gibts eine Funktion in der pibase

$this->pidList = $this->pi_getPidList($this->cObj->data['pages'],$this->cObj->data['recursive']);

installiere Dir extdeveval, dann hast Du eine offline doku der wichtigsten Befehle.

jenses ·
Booley schrieb

Oder meinst du, es würde mir helfen, wenn ich mit "exec_SELECTquery" arbeite?

Z.B.

$GLOBALS['TYPO3_DB']->exec_SELECTquery(
	$select_fields = '*',
	$from_table = 'tx_dgsimmo_obj',
	$where_clause = '
	      uid_stadtteil = 3 union SELECT * FROM tx_dgsimmo_obj
	      where tx_dgsimmo_obj.uid_stadtteil in 
	      (select uid from tx_dgsimmo_stadtteil
	     	 where uid_stadtteilreg =
		      (select uid_stadtteilreg from tx_dgsimmo_stadtteil
		      	where uid = 3
		      )
	      ) 	
	'
);

Das sollte doch deine Ursprungs-Query erzeugen, oder???

Booley schrieb

Ich sehe da allerdings keine wirklichen Unterschied zu "pi_exec_query".

Dann schau dir die Funktionen nochmal genau an...

Stoneage ·

Ein Union ist dann sinnvoll wenn Du eine Abfrage über mehrere Tabellen mit unterschiedlichen Spaltenanzahl hast. Dann kannst Du mit "SELECT ...,0,..." (0 ist eine Konstante) die folgende Fehlermeldung vermeiden:

"#1222 - The used SELECT statements have a different number of columns"

Booley ·

Ich habe jetzt "$GLOBALS['TYPO3_DB']->exec_SELECTquery" benutzt und mich selbst um die Sortierung gekümmert.

@steffenk:
Ich dachte, dass "$GLOBALS['TYPO3_DB']->sql_query($sql);" zum DBAL gehört. Aber da lag ich wohl daneben. 😃

Und vielen Dank für die PID-Liste, das hat super funktioniert!

@jenses:
Ich finde folgende Unterschiede:
exec_SELECTquery gibt einen MySql-Poniter und pi_exec_query einen SQL Pointer. Macht das einen Unterschied für mich?

Ansonsten hat pi_exec_query noch einen Parameter für mm-Verknüpfungen
Habe ich was Wichtiges übersehen?

@Tetramatrix:
Ich nutze hier ein UNION auf die gleiche Tabelle, da ich zunächst eine speziellere Datenmenge anzeigen will (mit einem speziellen Stadtteil) und anschließend alle weiteren der Region. Die Objekte des speziellen Stadtteils sollen zudem halt immer oben stehen.

Mir ist klar, dass man ein UNION eher benutzt, wenn man zwei Tabellen hat. Aber wie wäre es sonst zu lösen? Ich bin für alles offen, was mir hilft.

@all: Wenn ich hier Blödsinn schreibe/frage, dass tut mir das echt leid. Ich bin halt noch ganz am Anfang, was die Extensions angeht. Habt Nachsicht. :o

Ansonsten möchte ich mich hier mal für die tolle Hilfe bedanken. Ohne euch würde ich wirklich verzweifeln. *verbeug*

Schönen Sonntag noch
Booley

PS:
Da ich das eigentliche Problem als gelöst ansehe, schließe ich den Thread schon einmal. Die Antworten auf meine Fragen sind natürlich immernoch erwünscht!