[NDB] Join 3 tabulek k jedné hlavní

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

Zdravim,
jde nějak s Nette Database spojit 3 tabulky?
Mám tabulku products a k té chci doplnit informace product_baleni, product_translate.
Jde to nějak?
díky

ještě doplním, že by si představoval nějaký sql jako:

SELECT * FROM product p
  LEFT JOIN product_baleni pb
    ON p.id = pb.product_id
  LEFT JOIN product_translate pt
    ON p.id = pt.product_id
-- WHERE p.id = ?

Editoval CZechBoY (8. 5. 2013 18:31)

saimons
Člen | 293
+
0
-

Jo jde pomoci teckove nebo dvojteckove notaze viz. http://public.skrasek.com/…_2012_04_28/#1

Petr Hudík
Člen | 49
+
0
-

Nejsem si jistý, zda jsem schéma db pochopil zcela správně, ale myslím, že bys měl začít vytáhnutím produkti a jeho balení/překlad si vytáhnout až při výpisu.

Produkt můžeš vytáhnout takto:

$product = $db->table('product')->get($id);

// vypsat překlad můžeš takto (předpokládá že 'translate' je sloupec v tabulce product_translate)
$translate = $product->product_translate->translate;

// podobně se můžeš dostat i balení (opět předpokládá 'type', 'size')...
$type = $product->product_baleni->type;
$size = $product->product_baleni->size;
//...

Editoval Petr Hudík (9. 5. 2013 10:25)

CZechBoY
Člen | 3608
+
0
-

saimons: tam jsem to moc nepochopil
Petr Hudík: jasně, ale já potřebuju vypsat všechny možný balení produktu

plusminus databaze:
product: id, category_id
product_translate: product_id, language_id, nazev, popis (1:1)
product_baleni: product_id, language_id, baleni, cena (1:N)
product_pdf: product_id, language_id, pdf_cesta, pdf_typ (1:N)

saimons
Člen | 293
+
0
-
$database->teble('product')->select('product_translate.*')->select('product_baleni:*')->where('id', $id);

Ale uprimne si myslim, ze by jsi to mel delat pres funkci related().

Editoval saimons (14. 5. 2013 0:37)

CZechBoY
Člen | 3608
+
0
-

už to mám přes related
akorát mám problém, že to někdy vyhodí error:

Nette\InvalidStateException
Row does not contain primary column data.

zvláštní je, že jen někdy – třeba teď jsem k tomu potřeboval 5 refreshů

jo ještě kod, který to způsobuje :D

			$polozka['pdf'] = $p->related('product_pdf')
							->where('language_id', (int)$langID)
							->where('product_id', $p->id)
							->fetchPairs('typ', 'pdf')
							;

Editoval CZechBoY (2. 6. 2013 23:49)

saimons
Člen | 293
+
0
-

Tohle tam podle me nepatri (pokud jsem se neprehlidnul): ->where(‚product_id‘, $p->id); To Nette\Database udela samo, zjisti to podle systemove tabulky v DB pokud mas spravne nastavene FK.

CZechBoY
Člen | 3608
+
0
-

jasně, ale stejně to hází chybu, vůbec to nechápu

petr.pavel
Člen | 535
+
0
-

Možná by pomohlo, kdybys sem zkopíroval z panelu dotaz, který to pokládá do databáze, když to proběhne v pohodě. Předpokládám, že když to vykape na chybě, tak se dotaz nepoloží.

Jinak je divné, že ta hláška neobsahuje název atributu. Hláška pochází odtud (asi):
https://github.com/…ctiveRow.php#L98
a v obou případech obsahuje název atributu.

Asi sem taky budeš muset hodit dump struktury tvojí databáze. A jakým způsobem nakonec získáváš to $p.

CZechBoY
Člen | 3608
+
0
-

no teď jsem tam dal ještě ty blosti jako product_baleni_id, product_pdf_id (který stejně nepoužívám) a už to chyby nechází, mě by zajmalo jestli to jde udělat i bez toho primárního klíče
http://s5.postimg.org/…v/schema.jpg

petr.pavel
Člen | 535
+
0
-

Díky za schema. Ještě PHP kód, kterým získáváš $p.

CZechBoY
Člen | 3608
+
0
-

mi to vůbec neposílá upozornění na email, wtf

$product = $this->database->table('product')
		->where('product.category_id', $category['category_id']);


$products = array();
foreach($product as $p) {

	$translate = $p->related('product_translate')
		->select('name, description, spotreba')
		->where('language_id', (int)$langID)
		->fetch()
		;

	$polozka = array();
	$polozka['product_id'] = $p->id;
	$polozka['nazev'] = $translate->name;
	$polozka['popis'] = $translate->description;
	$polozka['spotreba'] = $translate->spotreba;
	$polozka['baleni'] = array();

	$baleni = $p->related('product_baleni')
				->where('language_id', (int)$langID)
				->order('cena DESC')
				->fetchPairs('baleni', 'cena')
				;

	$polozka['pdf'] = $p->related('product_pdf')
					->where('language_id', (int)$langID)
					//->where('product_id', $p->id)
					->fetchPairs('typ', 'pdf')
					;

	$polozka['baleni'] = $baleni;


   $products[] = $polozka;
}

takhle to mám teď, dělá to asi milion dotazů

CZechBoY
Člen | 3608
+
0
-

nikdo neví?
opět jsem se vrátil ke stejnému problému

hrach
Člen | 1838
+
0
-

fetchPairs dela vzdy novy dotaz, zkus se toho zbavit…