Join mezi 2 m:n tabulkami

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Jack06
Člen | 168
+
0
-

Zdravím, chci se zeptat, zda je a jak možné nad tímto návrhem databáze: http://www.2imgs.com/e0895872a1

Získat všechny stránky z daného menu, tedy:

$this->getTable('menu_pages')->where('menu_id', $id);

a k nim sloupeček namez tabulky pages_languages kde language_id = 1

Případně pokud se někomu nelíbí návrh a poradil by lepší, který by splňoval:

  • 0..* menu
  • 0..* stránek
  • každá stránka může mít více mutací
  • stránka patří minimálně do jednoho menu (stránka nikoli mutace)
  • každá stránka může patřit do více menu (každá stránka nikoli mutace)

Děkuji za rady

petr.pavel
Člen | 535
+
0
-

V NDB nedělám, ale tady je syntaxe NotORM, která je podobná. (nevyzkoušeno) Tuším, že umístění dvojteček je teď v NDB jinak.

$this->db->menu_pages()
  ->select('menu_pages.*, pages:pages_languages.name')
  ->where('menu_id', $id)
  ->where('pages:pages_languages.language_id', 1);

Z názvů tabulek a cizích klíčů vyplývá, že NDB se nemůže řídit jmennou konvencí (k tabulce pages by se musel odkazovat CK pages_id ne page_id), takže musíš mít definované cizí klíče na úrovni databáze.

Mimochodem, zezačátku jde především o to, jak sestavit dotaz v SQL a pak teprve o to, jak ho přepsat do NDB.
Na ladění dotazů v konferenci doporučuji sqlfiddle.com. Když pošleš odkaz na fiddle s definovaným schema a daty, lidi si raději svůj návrh vyzkouší a nebudou posílat blbosti :-)

hrach
Člen | 1844
+
0
-

No, podivej se na moji prednasku a slidy (hledej). Asi takto (z hlavy):

$context->table('pages')
	->where(':menu_pages.menu_id', 1)
	->where(':pages_languages.language_id', 1);

Zkraceny komentar a info s z prednasky: ano, muzes zacit na menu_pages, ale to nema vyznam, to primarni, co clovek dle me vybira je preci tedy stranky (aspon to pises v zadani, ziskat vsechny stranky).

Pokud bychom meli zacinat jako ty, tak pak asi:

$context->table('menu_pages')
	->where('menu_id', 1)
	->where('page:pages_languages.language_id', 1);
Jack06
Člen | 168
+
0
-

hrach napsal(a):

No, podivej se na moji prednasku a slidy (hledej). Asi takto (z hlavy):

$context->table('pages')
	->where(':menu_pages.menu_id', 1)
	->where(':pages_languages.language_id', 1);

Zkraceny komentar a info s z prednasky: ano, muzes zacit na menu_pages, ale to nema vyznam, to primarni, co clovek dle me vybira je preci tedy stranky (aspon to pises v zadani, ziskat vsechny stranky).

Pokud bychom meli zacinat jako ty, tak pak asi:

$context->table('menu_pages')
	->where('menu_id', 1)
	->where('page:pages_languages.language_id', 1);

No ten první backjoin mi hlásí No reference found for $page->menu_pages

Ten druhý hlásí: No reference found for $menu_pages->related(pages)

V databázi mi to vše frčí a tento SQL dotaz funguje:

	$this->getTable('menu_pages')
		->select('menu_pages.*')
		->select('page.pages_languages:name')
		->where('menu_id', $id);

Nicméně bych to potřeboval opravdu jako getTable z tabulky pages jak jsi psal první řešení.