Newsgroup: it.comp.www.php
Titolo: Lievemente OT: Query su una relazione many to many

Ho una relazione many to many fra due tabelle
Table1: Id-Book, Title 
Table2: Id-Keyword, Keyword 
Table3: Id-Book, Id-Keyword 
ciò che desidero ottenere è un'uscita del genere:
Title1 - Keyword1,Keyword2,Keyword3 
Title2 - Keyowrd1,Keyword4,Keyword5 
Title3 - Keyword2,Keyowrd5 
Title4 - Keyword3,Keyword6,Keyword7,Keyword8 
... 
il problema è che ad ogni riga corrisponde un numero diverso di campi. Un
metodo ben poco efficiente sarebbe quello di fare una query per avere tutti i
titoli e quindi per ogni titolo fare una query delle keyword ma una volta che i
libri sono più di 1000 mi pare che l'efficienza sarebbe piuttosto scarsa.
Avete un'idea di come potrei interrograre la query ?
grazie !!
Emiliano
-- 
Posted from 
pc83.fis.unipr.it
 [160.78.33.83] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 
 select a.title, c.keyword from table1 a, table2 b, table3 c
 where a.id_book=b.id_book and b.id_keyword=c.id_keyword  order by 1;
+--------+----------+
| title  | keyword  |
+--------+----------+
| title1 | keyword1 |
| title1 | keyword3 |
| title1 | keyword2 |
| title2 | keyword1 |
| title2 | keyword4 |
| title2 | keyword5 |
| title3 | keyword5 |
| title3 | keyword2 |
| title4 | keyword3 |
| title4 | keyword6 |
| title4 | keyword7 |
| title4 | keyword8 |
+--------+----------+
questo è quello che si può fare con mysql.
se hai un dbms più "serio" (oracle, mssql, sybase ecc.)
è possibile usare le nested query o stored procedures o (meglio) left join 
ma andiamo sul complicato e sul dispendioso in termini di memoria (per 
quanto riguarda le join).
se devi usare la query da php e hai mysql le left join non sono ancora 
supportate, ti conviene ciclare le tabelle all'interno del tuo codice.
(ci mettera pochissimi secondi in + su migliaia di record!)
ciao

Title4 - Keyword3,Keyword6,Keyword7,Keyword8 
SELECT Title, Keyword
	FROM Table1 [LEFT] JOIN Table3 ON Table1.Id-Book=Table3.Id-Book
		JOIN Table2 ON Table3.Id-Keyword = Table2.Id-Keyword;
e questo ti ritorna:
	Title1	Keyword1
	Title1	Keyword2
	Title1	Keyword3
	[Title7	(null)]
	Title2	Keyword1
	...
A questo punto siamo a cavallo: per es.:
	$exec = SQLExec($conn, ...);
	$Title = "";
	for($row = 0; $row <= $rows; $row++)
	{
		// Quando $row == $rows SQLArray ritorna NULL,
		// e questo e' diverso da $Title, forzando una
		// flush del buffer delle keywords.
		$data = SQLArray($exec, $row);
		if ($data["Title"] != $Title)
		{
			// Nuovo titolo.
			// Stampo il vecchio, a meno che sia
			// vuoto perche' ho appena iniziato.
			if ($Title <> "")
			{
				print "<TR><TD>$Title</TD>";
				print "<TD>$Keywords</TD></TR>\n";
			}
			// Aggiorno le variabili
			$Title = $data["Title"];
			$Keywords = "";
		}
		// Aggiungo questa keyword al running buffer.
		$Keyword = $data["Keyword"];
		$Urlify  = UrlEncode($Keyword);
		$Keyword = "<A
HREF=\"glossary.php?WORD=$Urlify\">$Keyword</A>";
		$Keywords .= "$Keyword&nbsp;";
	}
	// Se SQLExec() non ritorna NULL per indici > massimo, allora
	// quando arriviamo qui - e ci arriviamo con "$row < $rows" -
	// e' necessario fare un flush, o ci mangiamo l'ultimo record
	/*
	if ($Title <> "")
	{
		print "<TR><TD>$Title</TD>";
		print "<TD>$Keywords</TD></TR>\n";
	}
	*/
 
Leonardo
-- 
Nior thainig ar major i dtus an lae chugainn,
is ni rabhamar fein ann i gcoir na gceart
ach mar sheolfai aoireacht bo gan aoire,
ar thaobh na greine de Sliabh na mBan.