jen trochu slozitejsi dotaz v Database/Selection

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

Ahoj. Lámu si hlavu nad tím jak udělat jinak docela jednoduchý dotaz, ale pořád nevím jak to provést v Database/Selection. Mám uplně obyč tabulku s články, rozřazených do sekcí. Dále mám pole s ID několia sekcí.

Potřeboval bych načíst z každé této sekce člínek s nejvyšším ID a to tak, abych to mohl pak v šabloně procházet pomocí {foreach $articles as $article}, podobně jako když to načtu pomocí:

$this->template->articles = $this->context->createArticles()->where(array('sectionId'=>$section->id));

Dík moc!

castamir
Člen | 629
+
0
-

Máš na mysli tohle?

$this->template->articles = $this->context->createArticles()->where(array('sectionId'=>$section->id))->order("id DESC")->limit(1);

Editoval castamir (23. 8. 2012 14:28)

koren
Člen | 59
+
0
-

Dík, ale tohle buhužel ne. Potřebuju to hned z několika sekcí zároveň podle ídéček. Mám třeba array(1,2,4) a potřebuju vybrat jen z těchto sekcí.

Zkoušel jsem to stylem, že jsem procházel tohle pole pomocí foreach, pokaždé volal ten tvůj dotaz podle příslušného ID a výsledky nacpal do nového pole. Nepřišel jsem pak ale na způsob, jak výsledek procházet stjným stylem jako {foreach $articles as $article}. Pak už totiž neprocházím Nette\Database\Table\Selection, ale pole. A já bych to rád procházel jako Nette\Database\Table\Selection :)

Takže by mě zajímalo, jestli se to dá nacpat vše do jednoho dotazu, nebo jak tohle řešit.

castamir
Člen | 629
+
0
-

Pokud ale myslíš jediný select, který vypíše pro všechny unikátní výskyty sectionID takové řádky, které mají v rámci sectionID nejvyšší ID, tak si na to sestav klasický mysql dotaz. Ten lze pak snadno přepsat do nette. Další možnou alternativou je cyklické volání výše zmíněného selectu a spojení výsledků např.

$result = array();
for ($i = 0; $i < n; $i++) { // da se nahradit jinym cyklem
	$selection = $this->context->createArticles()->where(array('sectionId'=>$section->id))->order("id DESC")->limit(1);
	$result[] = $selection->fetch(); // prave ten jeden zaznam (viz ->limit(1))se prida do pole vysledku
}

$this->template->articles = $result;

EDIT: pro úplnost, jsem sjednotil oba příspěvky

Editoval castamir (23. 8. 2012 14:31)

koren
Člen | 59
+
0
-

funguje báječně, přesně tak jsem to potřeboval… díky moc!!

castamir
Člen | 629
+
0
-

ten mysql dotaz může vypadat nějak následovně:

SELECT *
FROM table
WHERE id IN (
SELECT MAX(id) FROM table GROUP by sectionId
)
GROUP BY sectionId ORDER BY id;

Stačí jen nahradit „table“ za název tabulky a je to

Editoval castamir (23. 8. 2012 14:52)

vvoody
Člen | 910
+
0
-

Ja by som vykonal nad tabuľkou GROUP by sekcie a nechal si vypísať MAX(id) a k nemu prislúchajúcu sekciu. Tento výsledok môžeš cachovať a invalidovať keď sa pridá nový článok, no a potom už len tieto max idčka selectnes a budeš ich mat v Nette\Database\Table\Selection.

Edit: no presne ako napisal castamir o 2 min skorej nez ja :D

Editoval vvoody (23. 8. 2012 14:57)

castamir
Člen | 629
+
0
-

No mě se nejdřív moc nechtělo ten dotaz vytvářet, ale pak jsem si řekl, že se mi to možná někdy bude hodit, a tak jsem ho sem dal…

Každopádně tohle je dotaz, na kterém se vlastně nemůže nic měnit, takže ho můžeš bezpečně volat tuším přes metodu

	$connection->query("vyse zmineny sql dotaz");