Wordpress WP_Query Multiple Queries - mysql

I'm trying to come up with a way of querying a CPT by a specific author but also if a meta_key has a specific value.
For example, my CPT has an author ID attached to it as well as a 'recipient' custom field. What i need is all posts of this type by this author as well as all posts of this type where 'recipient' = this author.
(Hope I've explained that well enough!)
I'm usually pretty OK with SQL but just having a random brain fart moment and can't figure this one out. Like I said, any help is much appreciated!
== Solved ==
Thanks to #3pepe3 for suggesting the meta_query parameter of WP_Query. Modified my CPT logic slightly and now have a beautifully working system.
The solution was to add a new meta field for each post containing the original sender's user id, then run two meta_queries to retrieve posts where the current user_id matches either the sender or recipient fields, likes so:
$args = array(
'post_type' => 'activity',
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'sender',
'value' => $user_id,
'type' => 'BINARY',
'compare' => '='
),
array(
'key' => 'recipient',
'value' => $user_id,
'type' => 'BINARY',
'compare' => '='
)
)
);
$query = new WP_Query( $args );

Helo JRM47R1X,
Instead of using SQL queries you should use the WP_Query Class
<?php
$args = array(
'post_type' => 'activity',
'author' => $user_id,
'post_status' => 'publish',
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'recipient',
'value' => $user_id,
'type' => 'BINARY',
'compare' => '='
),
),
);
$query = new WP_Query($args);
?>
The advantage of using the WP_Query is that you can mix meta queries, taxonomies and dates with logical operands like OR, AND BETWEEN....

Ok I eventually figured it out. Turns out all I needed was a Union on the two queries like so:
SELECT * FROM (
SELECT $wpdb->posts.*
FROM $wpdb->posts
WHERE $wpdb->posts.post_author = $user_id
AND $wpdb->posts.post_type = 'activity'
AND $wpdb->posts.post_status = 'publish'
UNION
SELECT $wpdb->posts.*
FROM $wpdb->posts, $wpdb->postmeta
WHERE $wpdb->postmeta.meta_key = 'recipient'
AND $wpdb->postmeta.meta_value = $user_id
AND $wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->posts.post_type = 'activity'
AND $wpdb->posts.post_status = 'publish'
) as x
ORDER BY x.post_date DESC
Hope this helps anyone else having this bizarrely obscure problem!

Related

How to get WooCommerce products from database based on multiple attributes

I want to get related products based on some criteria on product attributes like, the same sku, ean and gtin codes. But my query doesn't return any results. I tried different ways to query the database but all fail. Here is my query.
$sku = $product->get_sku();
$ean = $product->get_attribute( 'EAN' );
$gtin = $product->get_attribute( 'GTIN' );
$query = new WP_Query( array(
'post_type' => array('product'),
'posts_per_page' => 20,
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_sku',
'value' => $sku,
'compare' => '='
)
),
'tax_query' => array(
array(
'taxonomy' => 'pa_ean',
'field' => 'value',
'terms' => $ean,
'operator' => '=',
),
array(
'taxonomy' => 'pa_gtin',
'field' => 'value',
'terms' => $gtin,
'operator' => '=',
)
)
) );
By the way, if a product has ean code than it doesn't have a gtin and vice versa. It always has a sku which is unique to it self. But I have it added as a check to check if query at least returns value.
I can't find good documentary on this topic and hope someone here can help.

Wordpresss - WP_query count

I need to count how many times my date recorded in the meta key:metakey_AMC_data, in format (d-m-Y) it is contained in the database by comparing it with the current date
$mostra_data_corrente = date('d-m-Y');
$query = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}postmeta
WHERE (meta_key = 'metakey_AMC_data'
AND meta_value = '$mostra_data_corrente')");
$conta_risultati = count($query);
and this I can do perfectly.but now my need is to execute the first query by linking another AND, and specify when the term slug is equal to the category of the event (terms taxonomy), obviously the query is incorrect
SELECT * FROM {$wpdb->prefix}postmeta
WHERE (meta_key = 'metakey_AMC_data'
AND meta_value = '$mostra_data_corrente')
AND(slug = 'aperitivi') "
how can i do this?
You can get that count as well. You need to modify query (code) like follow:
$qry = array(
'post_type' => 'post', // mention your post type to narrow down searching through postmeta table
'meta_query' => array(
array(
'meta_key' => 'metakey_AMC_data',
'meta_value' => $mostra_data_corrente,
'compare' => '='
)
),
'tax_query' => array(
array(
'taxonomy' => 'nameoftaxonomy', // Write the name of taxonomy that you have assinged while you created a CPT (custom post type)
'field' => 'slug',
'terms' => 'aperitivi',
)
)
)
$the_query = WP_Query($qry);
echo $the_query->post_count;
You have to make some necessary changes in above code to suite your requirements. I've added comment where you have to do changes.

How to get count only today's post in get_terms wordpress

$termscat = get_terms([
'taxonomy' => 'newscategories',
'orderby' => 'count',
'order' => 'DESC',
'hide_empty' => false
]);
I am using above code to get post counts and is returning all post but i want to filter data only by todays date.
I think you want something like this.
SELECT count(post.ID) as count,rel.term_taxonomy_id,terms.name FROM {$wpdb->base_prefix}posts as post INNER JOIN {$wpdb->base_prefix}term_relationships as rel ON post.ID=rel.object_id INNER JOIN {$wpdb->base_prefix}terms as terms ON rel.term_taxonomy_id= terms.term_id WHERE post_date LIKE '$currentDate%' AND post.post_type='$post_type' GROUP BY rel.term_taxonomy_id ORDER BY count DESC
get_terms() used to get terms not posts.
if you want to get posts of current date then you can use the code below
$today = date( 'Y-m-d' );
$args = array(
'post_type' => 'vehicle',
'date_query' => array(
//set date ranges with strings!
'after' => 'today',
//allow exact matches to be returned
'inclusive' => true,
),
);
$query = new WP_Query( $args );
You can get more information on this https://codex.wordpress.org/Class_Reference/WP_Query#Date_Parameters
$today['year'] = current_time('Y');
$today['mon'] = current_time('m');
$today['mday'] = current_time('d');
$args = array(
'post_type' => 'news',
'date_query' => array(
array(
'year' => $today['year'],
'month' => $today['mon'],
'day' => $today['mday'],
),
),
'tax_query' => array(
array(
'taxonomy' => $tex_name,
'field' => 'term_id',
'terms' => $term_id,
),
),
);
$query = new WP_Query( $args );
$total = $query->found_posts;

ACF Field query by Repeater Field not empty

Been reading up on info for querying ACF Fields in wordpress here, having trouble with this bit though:
$args = array(
'posts_per_page' => -1,
'post_type' => 'team_member',
'status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'patents',
'value' => array(''),
'compare' => 'NOT IN'
)
)
);
$the_query = new WP_Query($args);
Basically, just trying to query all posts that have an ACF Repeater field, called patents that has at least 1 patent inside of it. How to do this?
I just had to deal with this myself, and what ended up working for me was querying for all posts where the value of the repeater field was greater than 0.
$args = array(
'posts_per_page' => -1,
'post_type' => 'team_member',
'status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'patents',
'value' => 0
'compare' => '>'
)
)
);
Mark's answer to search for 'patents' = 1 only returned posts where the repeater field had one value.
http://www.advancedcustomfields.com/resources/the_repeater_field/
Try to access the repeater field first, then call the WP_Query. If you were to do something like:
if( get_field('repeater_field_name', $post_id) )
Then call the sub_field and/or in this case the WP_Query.
There is also this syntax, you can gather all the posts you need then scroll through posts:
if( have_rows('repeater_field') ):
while( have_rows('repeater_field') ) : the_row();
$sub = get_sub_field('sub_field');
Maybe you can call the wp_query on this level?
just check if the value is true
$args = array(
'posts_per_page' => -1,
'post_type' => 'team_member',
'status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'patents',
'value' => true,
'compare' => '='
)
)
);
$the_query = new WP_Query($args);
Try this ..
This is not the standard solution for achieving the target but it will
work
Get all the post IDs whose repeater field(s) are there
<?php
$args = array(
'posts_per_page' => -1,
'post_type' => 'team_member',
'status' => 'publish',
'orderby' => 'title',
'order' => 'ASC',
);
$the_query = new WP_Query($args);
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
if ( have_rows('patents') ){
$allowed_ids[] = get_the_ID();
}
}
}
/* Restore original Post Data */
wp_reset_postdata();?>
Then run another Loop to get only those posts by their IDS
$args['post__in'] = $allowed_ids;
$the_query = new WP_Query($args);
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$patents = get_field('patents');//array
}}

SQL request does not work correctly

my problem is very simple. I have a table named 'articles' and I'd like to get the first three recent articles order DESC. But I want also these articles be displayed if their publication date is older or equal to today. So I've had an other condition in my request. My cakephp code is the following :
$this->set('lastArticles', $this->Article->find('all', array(
'conditions' => array('Article.visible' => true),
'Article.publication_date <= ' => date('Y-m-d'),
'order' => array('Article.creation_date DESC', 'Article.id DESC'),
'limit' => 3
)));
But the problem is even if the articles with a publication date > date('Y-m-d') these ones are displayed too! Does anyone have an idea ? Thanks in advance for your answer.
Looks like your publication_date condition isn't in the conditions array. Your code should look like this:
$this->set('lastArticles', $this->Article->find('all',
array(
'conditions' => array(
'Article.visible' => true,
'Article.publication_date <= ' => date('Y-m-d')
),
'order' => array(
'Article.creation_date DESC',
'Article.id DESC'
),
'limit' => 3
)));
A bit of extra indentation and whitespace is your friend here.
See this
$conditions = array(
'Article.visible' => true,
'Article.publication_date <= ' => date('Y-m-d')
);
$order = array('Article.creation_date DESC', 'Article.id DESC');
$lastArticles = $this->Article->find('all', array(
'conditions' => $conditions,
'order' => $order,
'limit' => 3
);
$this->set('lastArticles', $lastArticles);