Obtener la última publicación de todas las categorías en una sola consulta
Mi blog en WordPress tiene 12 categorías principales y 80 subcategorías.
Necesito obtener la última publicación de cada una de esas 12 categorías principales.
Sé cómo hacerlo con 12 consultas usando get_posts() 12 veces, pero ¿existe alguna forma de hacerlo con una sola consulta?
Intenté hacerlo funcionar así, pero obtengo más de 12 publicaciones:
// Obtener array de categorías (solo nivel 0)
$cats = array();
$categories = get_categories($args);
foreach($categories as $category) {
if ($category->parent == 0) {
$cats[] = $category->term_id;
}
}
$categories = implode(',', $cats);
// Obtener la última publicación de cada categoría
global $wpdb;
$querystr = "SELECT wposts.*
FROM $wpdb->posts wposts
LEFT JOIN $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
WHERE $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->term_taxonomy.term_id IN($categories)
ORDER BY wposts.post_date DESC";
$pageposts = $wpdb->get_results($querystr, OBJECT);
Y luego el bucle:
global $post;
foreach ($pageposts as $k=>$post):
setup_postdata($post);
// ... bucle de WordPress a través de los resultados
}

La cantidad de consultas no es la única medida de rendimiento, una consulta individual puede costar más que numerosas consultas simples.
El costo de (consulta pequeña) x12 < costo de consulta grande x1 + manipulación de strings/arrays
Sería mejor hacer las 12 consultas individuales. Si es costoso, almacena el resultado en un transitorio para usarlo más tarde y ahorrar procesamiento.
Pero aún mejor, también podrías actualizar los valores usando un hook en save_post para que no sea necesario "buscar", y se convierta en una simple operación de recuperar un valor almacenado. De esta manera, si lo almacenas y lo recuperas via get_option, no se ejecutarán consultas adicionales ya que WordPress ya ha cargado el valor y no hará una consulta SQL innecesaria para recuperarlo por segunda vez.
// en functions.php
function check_category_latest($post_id){
// verifica las categorías asignadas a este post
// para cada categoría asignada
// si es el más reciente en esa categoría
set_option('mytheme_cat_'.$term_id,$post_id);
}
add_hook('save_post','check_category_latest');
// donde quieras mostrar tus posts
$categories=get_categories($args);
foreach($categories as $category) {
$post_id = get_option('mytheme_cat_'.$category->term_id);
// haz lo necesario para mostrar el post
}
Algo en esas líneas te dará lo que buscas, y lo hará para todas las subcategorías también, además será mucho más económico que 12 consultas individuales, o incluso que 1 consulta grande y costosa
