Nette\Database a spojení tabulek s agregací

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

Ahoj, zápasím s Nette\Database:

Potřebuji vybrat celý obsah tabulky contactlists a ke každému záznamu vytáhnout z tabulky contacts počet příslušících záznamů se správným statusem. V SQL to lze jednoduše kódem níže. Můžetě mi poradit, nebo aspoň nakopnout správným směrem, jak to přepsat na Nette\Database\Selection? (potřebuji udělat datasource do niftygridu a nechce se mi dělat view v databázi)

$sql = "
SELECT
	lists_t.*,
	COUNT(distinct total_t.id) AS total,
	COUNT(distinct unconfirmed_t.id) AS unconfirmed,
	COUNT(distinct confirmed_t.id) AS confirmed,
	COUNT(distinct unsubscribed_t.id) AS unsubscribed,
	COUNT(distinct bounced_t.id) AS bounced

FROM
	contactlists lists_t

LEFT JOIN
	contacts total_t
		ON lists_t.id = total_t.contactlists_id

LEFT JOIN
	contacts unconfirmed_t
		ON
		lists_t.id = unconfirmed_t.contactlists_id AND
		unconfirmed_t.status = 0

LEFT JOIN
	contacts confirmed_t
		ON
		lists_t.id = confirmed_t.contactlists_id AND
		confirmed_t.status = 1

LEFT JOIN
	contacts unsubscribed_t
		ON
		lists_t.id = unsubscribed_t.contactlists_id AND
		unsubscribed_t.status = 2

LEFT JOIN
	contacts bounced_t
		ON
		lists_t.id = bounced_t.contactlists_id AND
		bounced_t.status = 3

GROUP BY lists_t.id
";

Editoval thunderbuff (1. 10. 2012 14:10)

hrach
Člen | 1838
+
0
-

Pokud bys te delal v nextras datagridu, pak si muzes definovat vlastni sablonu bunky a v ni korektne volat related a ref nad danym active row.

Coz je zasadni rozdil, v Database\Selection netahas data na jednoua, ale ty pocty vytahnes zvlast.

$row->count(':subscribed_t');
thunderbuff
Člen | 164
+
0
-

Nakonec jsem vytvořil view, to je asi nejjednodušší a celkem přímé řešení.

hrach
Člen | 1838
+
0
-

Jj, view je dobre, akorat na nem nejdou zjistit cizi klice. Coz je zasadni feature pro NDB.

Oli
Člen | 1215
+
0
-

Ahoj, mám podobný problém: potřebuji udělat datasource do niftygridu a udelal jsem uz pohled. Mám v podstate 2 moznosti. Bud pouzit to view, ktery me ale nefunguje v Nette. Pouzil jsem konstrukci:

return $this->_db->table("news_logs")

A hází mě to výjimku:

No reference found for $news_logs->

Je možný, že to je proto, že jsem na to view použil JOIN bez cizího klíče?

Druhá možnost by byla pokud by Nette umělo propojit 2 nesouvicející tabulky. Jde o to, že mám nějakou tabulku (např. novinky) a servisní tabulku logs, kde se logujou všechny změny jako: vytvoření novinky, editace novinky, … a já bych potřeboval v gridu novinky zobrazit i datum poslední editace a kdo naposledy editoval tu novinku. Protože těch tabulek je víc tak bych to nechtěl řešit cizími klíči, když navíc tabulka logs nesouvisí s vůbec žádnou tabulkou

Nebo tu je ještě nějaké jiné řešení? Díky moc za každou radu.

Junkman
Člen | 3
+
0
-

ja som mal tiez problem s JOIN. Situacia bola taka ze som mal tabulku v ktorej boli 2 stlpce a tie obsahovali idecka ktore odkazovali na prislusne tabulky. ked som chcel spojit stlpce tak mi hadzalo
No reference found for …
nakoniec som premenoval tie stlpce na nazovStlpca_nazovTabulky tak isto som spravil aj klucami.
Vyzeralo to nejak takto

table: everything

id id_something id_anything some_stuff

table: something

id name

table: anything

id name
mildabre
Člen | 62
+
0
-

Junkman napsal(a):

ja som mal tiez problem s JOIN. Situacia bola taka ze som mal tabulku v ktorej boli 2 stlpce a tie obsahovali idecka ktore odkazovali na prislusne tabulky. ked som chcel spojit stlpce tak mi hadzalo
No reference found for …
nakoniec som premenoval tie stlpce na nazovStlpca_nazovTabulky tak isto som spravil aj klucami.
Vyzeralo to nejak takto

table: everything

id id_something id_anything some_stuff

table: something

id name

table: anything

id name

Podle konvence kterou Jakub Vrána doporučuje použít pro názvy cizích klíčů ve vázaných tabulkách by Jsi měl místo id_everything použít everything_id viz http://www.notorm.com/#….

mildabre
Člen | 62
+
0
-

thunderbuff napsal(a):

Ahoj, zápasím s Nette\Database:

Potřebuji vybrat celý obsah tabulky contactlists a ke každému záznamu vytáhnout z tabulky contacts počet příslušících záznamů se správným statusem. V SQL to lze jednoduše kódem níže. Můžetě mi poradit, nebo aspoň nakopnout správným směrem, jak to přepsat na Nette\Database\Selection? (potřebuji udělat datasource do niftygridu a nechce se mi dělat view v databázi)

$sql = "
SELECT
	lists_t.*,
	COUNT(distinct total_t.id) AS total,
	COUNT(distinct unconfirmed_t.id) AS unconfirmed,
	COUNT(distinct confirmed_t.id) AS confirmed,
	COUNT(distinct unsubscribed_t.id) AS unsubscribed,
	COUNT(distinct bounced_t.id) AS bounced

FROM
	contactlists lists_t

LEFT JOIN
	contacts total_t
		ON lists_t.id = total_t.contactlists_id

LEFT JOIN
	contacts unconfirmed_t
		ON
		lists_t.id = unconfirmed_t.contactlists_id AND
		unconfirmed_t.status = 0

LEFT JOIN
	contacts confirmed_t
		ON
		lists_t.id = confirmed_t.contactlists_id AND
		confirmed_t.status = 1

LEFT JOIN
	contacts unsubscribed_t
		ON
		lists_t.id = unsubscribed_t.contactlists_id AND
		unsubscribed_t.status = 2

LEFT JOIN
	contacts bounced_t
		ON
		lists_t.id = bounced_t.contactlists_id AND
		bounced_t.status = 3

GROUP BY lists_t.id
";

Pro jaký databázový engine je určen SQL dotaz, který uvádíš ? Já pracuji pouze s MySQL a tahle syntax mě přijde divná, ale nejsem odborník. Nicméně jsem chtěl dát jinou poznámku:

Z toho SQL dotazu mě přijde, že máš nějaké entity např. katalog služeb které se jmenují list a jsou v hlavní tabulce lists_t. Na tuto tabulku jsou vázané výsledky nabídek těchto služeb uložené podle výsledku obchodu každý do samostatné tabulky: unconfirmed, confirmed, unsubscribed, bounced. Přijde mě to analyticky špatně. Výsledky obchodní akvizice je jedna entita a měla by ji vyjadřovat jedna tabulka např. acquisition která by měla rozlišit výsledek akvizice ve stavových polích např subscribe 0/1 (boolean), confirmad 0/1 (boolean) apod… Potom by Jsi např. nemusel psát takto krkolomné selecty ale použil by jsi SELECT * FROM lists_t LEFT JOIN acquisition WHERE .....

Co myslíš ? Do obchodní logiky samozřejmě vidět není, dá se pouze odhadovat z toho názvosloví.

jiri.pudil
Nette Blogger | 1032
+
0
-

mildabre: Je to zcela regulérní MySQL a dělá přesně to, co navrhuješ; joiny jsou všechny na jednu tabulku (contacts), jen je pokaždé jinak aliasovaná a pokaždé je v podmínce jiný status.

P.S. bych, bys, by, bychom, byste, by | mě X mně