seskupování položek podle údajů
<p>mám položky v mém seznamu a položky mají pole, které ukazuje datum vytvoření položky.</p><p> <a href="https://i.stack.imgur.com/ket2g.jpg"> <img src="https://i.stack.imgur.com/ket2g.jpg" alt="enter image description here"> </a> </p><p>a musím je seskupit na základě „komprese&ldquo;, kterou uživatel dává. možnosti jsou <code>day</code>, <code>week</code>, <code>month</code> a <code>year</code>.</p><p>pokud uživatel vybere <code>day</code> kompresi, musím své položky seskupit tak, aby položky, které byly vytvořeny ve stejný den, byly seskupeny. ve výše uvedeném příkladu jsou ve stejný den vytvořeny pouze položky 1 a 2. ostatní jsou také skupiny, ale budou mít pouze jednu položku, protože v den jejich vytvoření je vytvořena pouze jedna položka.</p><pre><code>{{item1, item2}, {item3}, {item4}, {item5}, {item6}, {item7}} </code></pre><p>pokud uživatel vybere <code>week</code>:</p><pre><code>{{item1, item2, item3, item4}, {item5}, {item6}, {item7}} </code></pre><p>pokud uživatel vybere <code>month</code>:</p><pre><code>{{item1, item2, item3, item4, item5}, {item6}, {item7}} </code></pre><p>pokud uživatel vybere <code>year</code>:</p><pre><code>{{item1, item2, item3, item4, item5, item6}, {item7}} </code></pre><p>po vytvoření skupin není důležité datum položek. myslím, že klíč může být cokoliv, dokud jsou skupiny vytvořeny.</p><p>v případě použití <code>map</code> jsem si myslel, že následující klíče jsou následující:</p><p><code>day</code> = den v roce<br> <code>week</code> = týden v roce<br> <code>month</code> = měsíc roku<br> <code>year</code> = rok<br></p><p>jaké by bylo nejlepší řešení tohoto problému? nemohl jsem to ani spustit a nemohu si představit jiné řešení než iteraci. </p>
<p>použil bych <code>collectors.groupingby</code> s upraveným <code>localdate</code> na klasifikátoru, takže položky s podobnými daty (podle <em>komprese</em> zadané uživatelem) jsou seskupeny dohromady.</p><p>nejprve vytvořte následující <code>map</code>:</p><pre><code>static final map&lt;string, temporaladjuster&gt; adjusters = new hashmap&lt;&gt;(); adjusters.put("day", temporaladjusters.ofdateadjuster(d -&gt; d)); // identity adjusters.put("week", temporaladjusters.previousorsame(dayofweek.of(1))); adjusters.put("month", temporaladjusters.firstdayofmonth()); adjusters.put("year", temporaladjusters.firstdayofyear()); </code></pre><p>poznámka: pro <code>"day"</code> je používáno <code>temporaladjuster</code>, které umožňuje nedotčené datum.</p><p>poté pomocí <code>compression</code> zadaného uživatelem dynamicky vyberte způsob seskupení seznamu položek:</p><pre><code>map&lt;localdate, list&lt;item&gt;&gt; result = list.stream() .collect(collectors.groupingby(item -&gt; item.getcreationdate() .with(adjusters.get(compression)))); </code></pre><p><code>localdate</code> se nastavuje metodou <a href="https://docs.oracle.com/javase/8/docs/api/java/time/localdate.html#with-java.time.temporal.temporaladjuster-"><code>localdate.with(temporaladjuster)</code></a> .</p>
<p>přiznávám, že jsem to nikdy předtím neudělal, takže došlo k trochu poškrábání hlavy. jednoduchá ukázková tabulka, která demonstruje:</p><pre><code>if exists (select * from sys.objects where object\_id = object\_id(n'[dbo].[mytable]') and type in (n'u')) drop table [dbo].[mytable] go create table dbo.mytable ( col1 int , col2 char(1) ) go insert dbo.mytable (col1, col2) values (1, 'a') insert dbo.mytable (col1, col2) values (1, 'b') insert dbo.mytable (col1, col2) values (1, 'c') insert dbo.mytable (col1, col2) values (2, 'a') insert dbo.mytable (col1, col2) values (2, 'b') insert dbo.mytable (col1, col2) values (2, 'c') insert dbo.mytable (col1, col2) values (3, 'a') insert dbo.mytable (col1, col2) values (3, 'b') insert dbo.mytable (col1, col2) values (3, 'c') </code></pre><p>pomocí parametru @sortstyle k rozlišení objednávek řazení se @sortstyle = 1 třídí podle <code>col1 asc, col2 desc</code> a @ sortstyle = 2 seřadit podle <code>col2 desc, col1 asc</code>.</p><pre><code>declare @sortstyle int set @sortstyle = 1 select col1 , col2 from dbo.mytable order by case when @sortstyle = 1 then col1 end asc, case when @sortstyle = 1 then col2 end desc, case when @sortstyle = 2 then col2 end desc, case when @sortstyle = 2 then col1 end asc set @sortstyle = 2 select col1 , col2 from dbo.mytable order by case when @sortstyle = 1 then col1 end asc, case when @sortstyle = 1 then col2 end desc, case when @sortstyle = 2 then col2 end desc, case when @sortstyle = 2 then col1 end asc </code></pre><p> <a href="https://dba.stackexchange.com/questions/4104/how-do-you-order-by-a-parameter/4111#4111">jak se objednáváte parametrem</a> pokrývá jednodušší případ třídění podle 1 sloupce.</p> Tvůj kód nehodlám číst, takže jen obecně. Na začátku před tím než budeš data řadit, tak si udělej jejich kopii. Pak si data seřaď a máš co jsi chtěl. V té kopii máš původní neseřazená data v původním pořadí. <p>protože ostatní odpovědi již naznačují, sql server může nebo nemusí explicitně zajistit, že řádky jsou seřazeny v pořadí seskupených indexů před <code>insert</code>.</p><p>to závisí na tom, zda má klastrovaný indexový operátor v plánu sadu vlastností <code>dmlrequestsort</code> (což zase závisí na odhadovaném počtu řádků, které jsou vloženy).</p><p>pokud zjistíte, že sql server to z jakéhokoli důvodu podceňuje, můžete mít prospěch z přidání explicitního <code>order by</code> k dotazu <code>select</code> k minimalizaci rozdělení stránek a následné fragmentaci z operace <code>insert</code></p><p><strong> příklad: </strong></p><pre><code>use tempdb; go create table t(n int primary key,filler char(2000)) create table t2(n int primary key,filler char(2000)) go declare @t table (u uniqueidentifier primary key default newid(),n int) insert into @t(n) select number from master..spt\_values where type = 'p' and number between 0 and 499 /*estimated row count wrong as inserting from table variable*/ insert into t(n) select t1.n*1000 + t2.n from @t t1, @t t2 /*same operation using explicit sort*/ insert into t2(n) select t1.n*1000 + t2.n from @t t1, @t t2 order by t1.n*1000 + t2.n select avg\_fragmentation\_in\_percent, fragment\_count, page\_count, avg\_page\_space\_used\_in\_percent, record\_count from sys.dm\_db\_index\_physical\_stats(2, object\_id('t'), null, null, 'detailed') ; select avg\_fragmentation\_in\_percent, fragment\_count, page\_count, avg\_page\_space\_used\_in\_percent, record\_count from sys.dm\_db\_index\_physical\_stats(2, object\_id('t2'), null, null, 'detailed') ; </code></pre><p>ukazuje, že <code>t</code> je masivně roztříštěný</p><pre><code>avg\_fragmentation\_in\_percent fragment\_count page\_count avg\_page\_space\_used\_in\_percent record\_count      99.3116118225536 92535 92535 67.1668272794663 250000 99.5 200 200 74.2868173956017 92535 0 1 1 32.0978502594514 200 </code></pre><p>ale pro <code>t2</code> fragmentace je minimální</p><pre><code>avg\_fragmentation\_in\_percent fragment\_count page\_count avg\_page\_space\_used\_in\_percent record\_count      0.376 262 62500 99.456387447492 250000 2.1551724137931 232 232 43.2438349394613 62500 0 1 1 37.2374598468001 232 </code></pre><p>naopak někdy budete chtít donutit sql server, aby podceňoval počet řádků, když víte, že data jsou již předem roztříděna a chcete zabránit zbytečnému třídění. jedním z pozoruhodných příkladů je vložení velkého počtu řádků do tabulky pomocí seskupeného indexového klíče <code>newsequentialid</code>. <a href="https://connect.microsoft.com/sqlserver/feedback/details/668540/unnecessary-sort-operation-for-insert-into-clustered-index-with-newsequentialid-key">ve verzích sql serveru před denali sql server přidává zbytečnou a potenciálně nákladnou operaci řazení</a> . tomu lze zabránit</p><pre><code>declare @var int =2147483647 insert into foo select top (@var) * from bar </code></pre><p>sql server poté odhadne, že bude vloženo 100 řádků bez ohledu na velikost <code>bar</code>, která je pod prahem, při kterém je do plánu přidáno řazení. jak je však uvedeno v poznámkách níže, znamená to, že vložka bohužel nebude moci využít výhody minimálního protokolování.</p> <p>příkaz <code>merge</code> má složitou syntaxi a ještě složitější implementaci, ale v zásadě jde o spojení dvou tabulek, filtrování dolů na řádky, které je třeba změnit (vložit, aktualizovat nebo smazat), a poté provést požadované změny. vzhledem k těmto vzorovým údajům:</p><pre><code>declare @categoryitem as table ( categoryid integer not null, itemid integer not null, primary key (categoryid, itemid), unique (itemid, categoryid) ); declare @datasource as table ( categoryid integer not null, itemid integer not null primary key (categoryid, itemid) ); insert @categoryitem (categoryid, itemid) values (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 5), (3, 6), (4, 5); insert @datasource (categoryid, itemid) values (2, 2); </code></pre><p><strong> cíl </strong></p><pre><code>╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 1 ║ 1 ║ ║ 2 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 3 ║ ║ 2 ║ 3 ║ ║ 3 ║ 5 ║ ║ 4 ║ 5 ║ ║ 3 ║ 6 ║ ╚════════════╩════════╝ </code></pre><p><strong> zdroj </strong></p><pre><code>╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 2 ║ 2 ║ ╚════════════╩════════╝ </code></pre><p>požadovaným výsledkem je nahrazení dat v cíli daty ze zdroje, ale pouze pro <code>categoryid = 2</code>. po výše uvedeném popisu <code>merge</code> bychom měli napsat dotaz, který spojuje zdroj a cíl pouze na klíče, a filtrovat řádky pouze v klauzulích <code>when</code>:</p><pre><code>merge into @categoryitem as target using @datasource as source on source.itemid = target.itemid and source.categoryid = target.categoryid when not matched by source and target.categoryid = 2 then delete when not matched by target and source.categoryid = 2 then insert (categoryid, itemid) values (categoryid, itemid) output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>to dává následující výsledky:</p><pre><code>╔═════════╦════════════╦════════╗ ║ $action ║ categoryid ║ itemid ║ ╠═════════╬════════════╬════════╣ ║ delete ║ 2 ║ 1 ║ ║ insert ║ 2 ║ 2 ║ ║ delete ║ 2 ║ 3 ║ ╚═════════╩════════════╩════════╝ ╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 1 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 3 ║ ║ 2 ║ 2 ║ ║ 3 ║ 5 ║ ║ 3 ║ 6 ║ ║ 4 ║ 5 ║ ╚════════════╩════════╝ </code></pre><p>realizační plán je: <img src="https://i.stack.imgur.com/fovhu.jpg" alt="merge plan"></p><p>všimněte si, že jsou obě tabulky plně naskenovány. můžeme to považovat za neefektivní, protože pouze řádky, kde <code>categoryid = 2</code> bude ovlivněno v cílové tabulce. zde přicházejí varování v books online. jeden chybný pokus o optimalizaci, aby se dotkl pouze nezbytných řádků v cíli, je:</p><pre><code>merge into @categoryitem as target using ( select categoryid, itemid from @datasource as ds where categoryid = 2 ) as source on source.itemid = target.itemid and target.categoryid = 2 when not matched by target then insert (categoryid, itemid) values (categoryid, itemid) when not matched by source then delete output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>logika v klauzuli <code>on</code> je použita jako součást spojení. v tomto případě je spojení úplným vnějším spojením (viz <a href="http://technet.microsoft.com/en-us/library/bb522522%28v=sql.105%29.aspx">tento záznam books online</a> proč). použití kontroly kategorie 2 na cílových řádcích jako součásti vnějšího spojení nakonec povede k odstranění řádků s jinou hodnotou (protože neodpovídají zdroji):</p><pre><code>╔═════════╦════════════╦════════╗ ║ $action ║ categoryid ║ itemid ║ ╠═════════╬════════════╬════════╣ ║ delete ║ 1 ║ 1 ║ ║ delete ║ 1 ║ 2 ║ ║ delete ║ 1 ║ 3 ║ ║ delete ║ 2 ║ 1 ║ ║ insert ║ 2 ║ 2 ║ ║ delete ║ 2 ║ 3 ║ ║ delete ║ 3 ║ 5 ║ ║ delete ║ 3 ║ 6 ║ ║ delete ║ 4 ║ 5 ║ ╚═════════╩════════════╩════════╝ ╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 2 ║ 2 ║ ╚════════════╩════════╝ </code></pre><p>kořenová příčina je ze stejného důvodu, proč se predikáty chovají v klauzuli vnější spojení <code>on</code> odlišně, než když jsou specifikovány v klauzuli <code>where</code>. syntaxe <code>merge</code> (a implementace spojení v závislosti na zadaných klauzulích) jen ztěžují vidět, že tomu tak je.</p><p> <a href="http://technet.microsoft.com/en-us/library/bb510625%28v=sql.105%29.aspx">navádění v books online</a> (rozšířeno v položce <a href="http://technet.microsoft.com/en-us/library/cc879317%28v=sql.105%29.aspx">optimizing performance</a> ) nabízí navádění, které zajistí, že správná sémantika je vyjádřena pomocí syntaxe <code>merge</code>, aniž by uživatel nutně musel muset pochopit všechny podrobnosti implementace nebo zohlednit způsoby, kterými by optimalizátor mohl legitimně přeskupit věci z důvodů efektivnosti provádění.</p><p>dokumentace nabízí tři možné způsoby implementace časného filtrování:</p><p><strong> zadání podmínky filtrování v klauzuli <code>when</code> </strong> zaručuje správné výsledky, ale může znamenat, že více řádků je čteno a zpracováno ze zdroje a cíle tabulky, než je nezbytně nutné (viz první příklad).</p><p><strong> aktualizace prostřednictvím zobrazení </strong>, která obsahuje podmínku filtrování, také zaručuje správné výsledky (protože změněné řádky musí být přístupné pro aktualizaci prostřednictvím zobrazení), ale vyžaduje to vyhrazené zobrazení, které splňuje liché podmínky pro aktualizaci zobrazení.</p><p><strong> použití společného výrazu tabulky </strong> přináší podobné riziko při přidávání predikátů k klauzuli <code>on</code>, ale z poněkud odlišných důvodů. v mnoha případech to bude bezpečné, ale vyžaduje to odbornou analýzu prováděcího plánu, aby se to potvrdilo (a rozsáhlé praktické testování). například:</p><pre><code>with target as ( select * from @categoryitem where categoryid = 2 ) merge into target using ( select categoryid, itemid from @datasource where categoryid = 2 ) as source on source.itemid = target.itemid and source.categoryid = target.categoryid when not matched by target then insert (categoryid, itemid) values (categoryid, itemid) when not matched by source then delete output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>výsledkem jsou správné výsledky (neopakované) s optimálnějším plánem:</p><p><img src="https://i.stack.imgur.com/tazmk.jpg" alt="merge plan 2"></p><p>plán čte pouze řádky pro kategorii 2 z cílové tabulky. to může být důležitým hlediskem výkonu, pokud je cílová tabulka velká, ale je příliš snadné tuto chybu získat pomocí syntaxe <code>merge</code>.</p><p>někdy je snazší zapsat <code>merge</code> jako samostatné operace dml. tento přístup může dokonce <strong> vést lépe </strong> než jediný <code>merge</code>, což je skutečnost, která lidi často překvapuje.</p><pre><code>delete ci from @categoryitem as ci where ci.categoryid = 2 and not exists ( select 1 from @datasource as ds where ds.itemid = ci.itemid and ds.categoryid = ci.categoryid ); insert @categoryitem select ds.categoryid, ds.itemid from @datasource as ds where ds.categoryid = 2; </code></pre> <p>pokud se dostáváte do bodu, kdy kód ve vašem <code>functions.php</code> tématu začíná přemoci vás, určitě bych řekl, že jste připraveni zvážit rozdělení do několika souborů. v tomto bodě mám sklon dělat to téměř druhou povahou.</p><h3>použít zahrnout soubory do souboru <code>functions.php</code> soubor</h3><p>vytvořím podadresář nazvaný<em> "zahrnuje" </em>pod mým adresářem motivů a segmentuji můj kód do souborů organizovaných podle toho, co mi v té době dává smysl (což znamená, že jsem neustále refactoring a pohybující se kód kolem webu se vyvíjí. ) také zřídka v reálném kódu v <code>functions.php</code>; vše jde v souborech zahrnujících; jen moje preference.</p><p>jen abych vám dal příklad zde je moje zkušební instalace, kterou používám k testování svých odpovědí na otázky zde na wordpress odpovědi. pokaždé, když odpovím na otázku, mám kód v případě, že ji potřebuji znovu. to není přesně to, co budete dělat pro živé stránky, ale ukazuje mechaniku rozdělení kódu:</p><pre><code>&lt;?php /* * functions.php * */ require\_once( \_\_dir\_\_ . '/includes/null-meta-compare.php'); require\_once( \_\_dir\_\_ . '/includes/older-examples.php'); require\_once( \_\_dir\_\_ . '/includes/wp-admin-menu-classes.php'); require\_once( \_\_dir\_\_ . '/includes/admin-menu-function-examples.php'); // wa: adding a taxonomy filter to admin list for a custom post type? // http://wordpress.stackexchange.com/questions/578/ require\_once( \_\_dir\_\_ . '/includes/cpt-filtering-in-admin.php'); require\_once( \_\_dir\_\_ . '/includes/category-fields.php'); require\_once( \_\_dir\_\_ . '/includes/post-list-shortcode.php'); require\_once( \_\_dir\_\_ . '/includes/car-type-urls.php'); require\_once( \_\_dir\_\_ . '/includes/buffer-all.php'); require\_once( \_\_dir\_\_ . '/includes/get-page-selector.php'); // http://wordpress.stackexchange.com/questions/907/ require\_once( \_\_dir\_\_ . '/includes/top-5-posts-per-category.php'); // http://wordpress.stackexchange.com/questions/951/ require\_once( \_\_dir\_\_ . '/includes/alternate-category-metabox.php'); // http://lists.automattic.com/pipermail/wp-hackers/2010-august/034384.html require\_once( \_\_dir\_\_ . '/includes/remove-status.php'); // http://wordpress.stackexchange.com/questions/1027/removing-the-your-backup-folder-might-be-visible-to-the-public-message-generate require\_once( \_\_dir\_\_ . '/includes/301-redirects.php'); </code></pre><h3>nebo vytvořit moduly</h3><p>další možností je začít seskupovat kód podle funkce a vytvořit si vlastní pluginy. pro mě začnu kódování v souboru <code>functions.php</code> a v době, kdy dostanu kód, jsem přesunul většinu kódu do pluginů.</p><h3>nicméně žádná významná výkonnost pochází z php kódové organizace</h3><p>na druhou stranu strukturování souborů php je 99% o vytvoření objednávky a udržovatelnosti a 1% o výkonu, pokud (organizování souborů <code>.js</code> a <code>.css</code>, které prohlížeč přes http volá, je zcela odlišný případ a má obrovský rozsah ale jak si organizujete svůj php kód na serveru do značné míry z hlediska výkonu nezáleží.</p><h3>organizace code je osobní preferencí</h3><p>a v neposlední řadě organizace kódu je osobní preference. někteří lidé by nenáviděli, jak organizuji kód, stejně jako bych mohl nenávidět, jak to taky dělají. najděte si něco, co se vám líbí a držte se ho, ale dovolte, aby se vaše strategie v průběhu času vyvíjela, abyste se s ní dozvěděli více a lépe se s ní spokojili.</p> Videl bych to na prava na slozce. Pouzivam osobne XP, ale na nich se musi v moznostech slozky odzaskrtnout pole pouzivat zjednodusene sdileni. Po te pri kazdem nastavovani sdileni slozky pribude zalozka s pravama, kde se da nastavit uzivatel nebo skupina, ktera do slozky muze vstupovat, zapisovat atd. <p>sloupec můžete třídit do sestupného formátu a poté pouze získat hodnotu z n-tého řádku.</p><p>upravit::</p><p>aktualizováno podle požadavku na komentář.<strong> <em>upozorněn&iacute;</em> </strong>zcela nevyzkoušené!</p><pre><code>select dob from (select dob from users order by dob desc) where rowid = 6 </code></pre><p>něco takového by mělo fungovat pro oracle ... možná budete muset nejprve dostat syntaxi!</p> Jaky mas nastaven datum a cas? <p>mám sklon souhlasit se svým šéfem :) možná, že skutečná aplikace má jiný pocit, ale podle vzhledu makety se nezdá být velmi elegantní.</p><p>co se stane, když po výběru podkategorie změním kategorii, resetuje se tato podkategorie? a pokud vyberu několik kategorií, obsahuje rozbalovací nabídka podkategorie podkategorie všech kategorií, které jsem vybral?</p><p>výběr několika kategorií současně vyžaduje hodně práce, protože rozevírací seznam se po kliknutí zavře a je třeba jej znovu otevřít po každé přidané položce a znovu ji naskenovat, abyste našli další potřebnou položku.</p><p>vaše odpověď zní jako rozevírací/vyskakovací strom se zaškrtávacími políčky.</p> <p>to, co chcete, je možné, ale bude vyžadovat, abyste se ponořili do<strong> sql, kterému se chci vyhnout, kdykoli je to možné </strong>(ne proto, že to nevím, jsem vývojář sql, ale protože<strong> in wordpress chcete použít api kdykoli je to možné </strong>minimalizovat budoucí problémy s kompatibilitou související s budoucími potenciálními změnami struktury databáze.)</p><h2>sql s operátorem <code>union</code> je možnost</h2><p>chcete-li použít sql, co potřebujete, je operátor <code>union</code> ve vašem dotazu, něco takového za předpokladu, že vaše kategorie slugs jsou <code>"category-1"</code>, <code>"category-1"</code> a <code>"category-3"</code>:</p><pre><code>select * from wp\_posts where id in ( select tr.object\_id from wp\_terms t inner join wp\_term\_taxonomy tt on t.term\_id = tt.term\_id inner join wp\_term\_relationships tr on tt.term\_taxonomy\_id = tr.term\_taxonomy\_id where tt.taxonomy='category' and t.slug='category-1' limit 5 union select tr.object\_id from wp\_terms t inner join wp\_term\_taxonomy tt on t.term\_id = tt.term\_id inner join wp\_term\_relationships tr on tt.term\_taxonomy\_id = tr.term\_taxonomy\_id where tt.taxonomy='category' and t.slug='category-2' limit 5 union select tr.object\_id from wp\_terms t inner join wp\_term\_taxonomy tt on t.term\_id = tt.term\_id inner join wp\_term\_relationships tr on tt.term\_taxonomy\_id = tr.term\_taxonomy\_id where tt.taxonomy='category' and t.slug='category-3' limit 5 ) </code></pre><h2>sql union můžete použít s <code>posts\_join</code> filtrem</h2><p>pomocí výše uvedeného můžete buď<strong> jen zavolat přímo </strong>nebo můžete<strong> použít <code>posts\_join</code> háček filtru </strong>jako následovně; poznámka používám <a href="http://www.phpf1.com/tutorial/php-heredoc-syntax.html"><strong> php heredoc </strong></a> , takže se ujistěte, že <code>sql;</code> je flush vlevo. také jsem si všiml, že jsem použil globální var, abych vám umožnil definovat kategorie mimo háček výčtem kategorie slimáků v poli. tento kód můžete umístit do pluginu nebo do souboru <code>functions.php</code> motivu:</p><pre><code>&lt;?php global $top\_5\_for\_each\_category\_join; $top\_5\_for\_each\_category\_join = array('category-1','category-2','category-3'); add\_filter('posts\_join','top\_5\_for\_each\_category\_join',10,2); function top\_5\_for\_each\_category\_join($join,$query) { global $top\_5\_for\_each\_category\_join; $unioned\_selects = array(); foreach($top\_5\_for\_each\_category\_join as $category) { $unioned\_selects[] =&lt;&lt;&lt;sql select object\_id from wp\_terms t inner join wp\_term\_taxonomy tt on t.term\_id = tt.term\_id inner join wp\_term\_relationships tr on tt.term\_taxonomy\_id = tr.term\_taxonomy\_id where tt.taxonomy='category' and t.slug='{$category}' limit 5 sql; } $unioned\_selects = implode("\n\nunion\n\n",$unioned\_selects); return $join . " inner join ($unioned\_selects) categories on wp\_posts.id=categories.object\_id " ; } </code></pre><h2>ale mohou být vedlejší účinky</h2><p>samozřejmě s použitím háčků pro modifikaci dotazů, jako je <code>posts\_join</code>, vždy zvou vedlejší efekty v tom, že působí globálně na dotazy, a proto je obvykle nutné zabalit vaše změny do <code>if</code>, které je používají pouze v případě potřeby a jaká kritéria pro testování mohou být složitá.</p><h2>zaměřte se spíše na optimalizaci?</h2><p>domnívám se však, že vaše otázka se týká<strong> více o optimalizaci </strong>než o tom, že dokážete udělat 5 nejlepších dotazů v čase 3, ne? pokud tomu tak je, pak možná existují další možnosti, které používají wordpress api?</p><h2>lepší je použití přechodových api pro ukládání do mezipaměti?</h2><p>předpokládám, že vaše příspěvky se nezmění tak často, správně? co když přijmete periodicky tří (3) dotaz a poté výsledky uložíte pomocí <a href="http://codex.wordpress.org/transients\_api"><strong> transients api </strong></a> ? získáte udržovatelný kód a skvělý výkon; dobrý bit lepší než <code>union</code> dotaz výše, protože wordpress uloží seznamy příspěvků jako serializované pole v jednom záznamu tabulky <code>wp\_options</code>.</p><p>chcete-li si to vyzkoušet, můžete provést následující příklad a vložit jej do kořenového adresáře webu jako <code>test.php</code>:</p><pre><code>&lt;?php $timeout = 4; // 4 hours $categories = array('category-1','category-2','category-3'); include "wp-load.php"; $category\_posts = get\_transient('top5\_posts\_per\_category'); if (!is\_array($category\_posts) || count($category\_posts)==0) { echo "hello every {$timeout} hours!"; $category\_posts = array(); foreach($categories as $category) { $posts = get\_posts("post\_type=post&amp;numberposts=5&amp;taxonomy=category&amp;term={$category}"); foreach($posts as $post) { $category\_posts[$post-&gt;id] = $post; } } set\_transient('top5\_posts\_per\_category',$category\_posts,60*60*$timeout); } header('content-type:text/plain'); print\_r($category\_posts); </code></pre><h2>souhrn</h2><p>zatímco ano, můžete udělat to, co jste požadovali pro použití dotazu sql <code>union</code> a háčku <code>posts\_join</code>, což je pravděpodobně lepší nabídka pomocí mezipaměti s<strong> <em>transients api</em> </strong>.</p><p>snad to pomůže?</p>