This example illustrates how to query an array of post IDs from a custom DB table then use the array in a WP_Query.
This can be much faster than using meta queries on a WP_Query object, particularly if you are matching multiple fields.
| <?php | |
| // Declare the global wpdb variable | |
| global $wpdb; | |
| // Write our custom query. In this query, we're only selecting the post_id field of each row that matches our set of | |
| // conditions. Note the %s placeholders – these are dynamic and indicate that we'll be injecting strings in their place. | |
| $SQL = "SELECT `post_id` FROM `wp_custom_db_table` | |
| WHERE `date_start` >= %s | |
| AND `location` = %s | |
| ORDER BY `date_start` ASC;"; | |
| // Use $wpdb's prepare() method to replace the placeholders with our actual data. Doing it this way protects against | |
| // injection hacks as the prepare() method santizes the data accordingly. The output is a prepared, sanitized SQL | |
| // statement ready to be executed. | |
| $SQL = $wpdb->prepare( $SQL, current_time( 'Ymd' ), 'some location' ); | |
| // Query the database with our prepared SQL statement, fetching the first column of the matched rows. In our case, we | |
| // only queried the post_id field of each row so we know that the post_id fields will be the first column. The result | |
| // here is an array of post_ids (provided we have a match) | |
| $post_ids = $wpdb->get_col( $SQL ); | |
| if ( $post_ids ) { | |
| // When calling WP_Query, we no longer need to worry about specifying a post type because we know exactly which post | |
| // IDs we're after. We've also already ensured the correct order of our post IDs through the ORDER BY xxx ASC | |
| // portion of our SQL query. So, we just tell WP_Query to return the WP_Post objects in the order of the post IDs we | |
| // pass to it. | |
| $query = new WP_Query( [ | |
| 'post__in' => $post_ids, | |
| 'post_type' => 'any', | |
| 'posts_per_page' => 4, | |
| 'orderby' => 'post__in', | |
| ] ); | |
| // The rest is exactly as you normally would handle a WP_Query object. | |
| if ( $query->have_posts() ) { | |
| while ( $query->have_posts() ) { | |
| $query->the_post(); | |
| // Do yo thang... | |
| } | |
| wp_reset_postdata(); | |
| } | |
| } else { | |
| // … | |
| } |