Nette\Database a spojení tabulek s agregací
- thunderbuff
- Člen | 164
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)
- Oli
- Člen | 1215
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
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
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 taktotable: 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
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
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ě