What´s the problem with this?
I´m trying to search in wp_postmeta and wp_terms but i getting just one or another, never both. I already tried change OR to AND in WHERE, but nothing happens and no result is printed.
Thanks!
$join .= "
LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id
LEFT JOIN $wpdb->term_relationships ON $wpdb->posts.ID = $wpdb->term_relationships.object_id
INNER JOIN $wpdb->term_taxonomy ON $wpdb->term_taxonomy.term_taxonomy_id = $wpdb->term_relationships.term_taxonomy_id
INNER JOIN $wpdb->terms ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id
";
and this...
$where .= "
OR ( $wpdb->postmeta.meta_value LIKE '%".get_search_query()."%' AND $wpdb->posts.post_status = 'publish' )
OR ( $wpdb->terms.name LIKE '%".get_search_query()."%' AND $wpdb->posts.post_status = 'publish' )
";
UPDATE 1
After reading here https://support.advancedcustomfields.com/forums/topic/mistake-in-documentation-query-posts-by-custom-fields/ — I´ve changed the two "inner join" for "join" and it worked fine. I don´t know exactly why it works. But unfortunately still very slow to get the results.
Could you tell me if this is the best approach for what I'm looking for?
add_filter( 'posts_join', 'custom_search_join' );
add_filter( 'posts_where', 'custom_search_where' );
add_filter( 'posts_distinct', 'custom_search_distinct' );
function custom_search_join( $join ) {
global $wpdb;
if( !is_admin() ) {
if( is_search() ) {
$join .= "
LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id
LEFT JOIN $wpdb->term_relationships ON $wpdb->posts.ID = $wpdb->term_relationships.object_id
LEFT JOIN $wpdb->term_taxonomy ON $wpdb->term_taxonomy.term_taxonomy_id = $wpdb->term_relationships.term_taxonomy_id
LEFT JOIN $wpdb->terms ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id
";
print_r( $join ) ;
}
}
return $join;
}
function custom_search_where( $where ) {
global $wpdb;
if( !is_admin() ) {
if( is_search() ) {
$where .= "
OR ( $wpdb->postmeta.meta_value LIKE '%".get_search_query()."%' )
OR ( $wpdb->terms.name LIKE '%".get_search_query()."%' )
AND $wpdb->posts.post_status = 'publish'
";
print_r( $where ) ;
}
}
return $where;
}
function custom_search_distinct( $where ) {
global $wpdb;
if( !is_admin() ) {
if( is_search() ) {
return "DISTINCT";
}
}
return $where;
}
UPDATE 2
After some research and study.
Define list of ACF fields that will be searched
Define taxonomies to be searched
Running fast so far.
If anyone knows of a way to improve this code I really appreciate it.
add_filter( 'posts_search', 'busca_acf', 500, 2 );
function lista_campos_acf() {
$lista_campos_acf = [ 'acf-field-example' ];
return $lista_campos_acf;
}
function lista_taxonomias() {
$lista_taxonomias = [ 'post_tag', 'category', 'example_taxonomy' ];
return $lista_taxonomias;
}
function busca_acf( $where, $wp_query ) {
if( !is_admin() ) {
global $wpdb;
$termos = remove_accents( $wp_query->query_vars[ 's' ] );
$exploded = array_map( 'strtolower', explode( ' ', $termos ) );
$lista_campos_acf = lista_campos_acf();
$lista_taxonomias = lista_taxonomias();
$where = '';
foreach( $exploded as $tag ) {
$where .= "
AND (
( wp_posts.post_title LIKE '%$tag%' )
OR ( wp_posts.post_content LIKE '%$tag%' )
OR EXISTS (
SELECT *
FROM wp_postmeta
WHERE post_id = wp_posts.ID
AND ( ";
foreach( $lista_campos_acf as $campo_acf ) {
if( $campo_acf == $lista_campos_acf[0] ) {
$where .= " ( meta_key LIKE '%" . $campo_acf . "%' AND meta_value LIKE '%$tag%' ) ";
}
else {
$where .= " OR ( meta_key LIKE '%" . $campo_acf . "%' AND meta_value LIKE '%$tag%' ) ";
}
}
$where .= ")
)
OR EXISTS (
SELECT *
FROM wp_terms
INNER JOIN wp_term_taxonomy ON wp_term_taxonomy.term_id = wp_terms.term_id
INNER JOIN wp_term_relationships ON wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
WHERE ( ";
foreach ( $lista_taxonomias as $tax ) {
if( $tax == $lista_taxonomias[0] ) {
$where .= "taxonomy = '" . $tax . "'";
}
else {
$where .= "OR taxonomy = '" . $tax . "'";
}
}
$where .= ")
AND object_id = wp_posts.ID
AND wp_terms.name LIKE '%$tag%'
)
)
";
}
return $where;
}
}
Related
My query is failing everytime I run it. This error keeps showing
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'BY b.bidId DESC' at line 1Database select query failed.
public static function getAuctionBids( $auctionId, $limit = null )
{
self::getDatabaseInstance();
// SQL query for retrieving all bids for a specific auction
$bidsQuery = "SELECT u.username AS bidderName, u.userId AS bidderId, b.bidTime, b.bidPrice ";
$bidsQuery .= "FROM auctions a, bids b, users u ";
$bidsQuery .= "WHERE a.auctionId = b.auctionId AND b.userId = u.userId AND a.auctionId = $auctionId ";
$bidsQuery .= "ORDER BY b.bidId DESC";
$bidsQuery .= ( is_null( $limit ) ) ? "" : " LIMIT " . $limit;
$result = self::$database -> issueQuery( $bidsQuery );
$bids = [];
while ( $row = $result -> fetch_assoc() )
{
$bid = new Bid( $row );
$bids[] = $bid;
}
return $bids;
}
I have this query right now
global $wpdb;
$interval = "1 WEEK";
$now = current_time('mysql');
$top4=$wpdb->get_results('SELECT ID, post_title, post_name from `'.$wpdb->prefix.'popularpostssummary`
INNER JOIN `'.$wpdb->prefix.'posts` ON `postid`=`ID`
ORDER BY `pageviews` DESC
LIMIT 4;', ARRAY_A);
And I want to add the following conditions, what's the proper way of adding them in the code?
WHERE post_type = post
AND last_viewed > DATE_SUB('{$now}', INTERVAL {$interval})
post_type is under '.$wpdb->prefix.'posts
while last_viewed is under '.$wpdb->prefix.'popularpostssummary
global $wpdb;
$interval = "1 WEEK";
$now = current_time('mysql');
$sql =
'SELECT p.ID, p.post_title, p.post_name
FROM `' . $wpdb->prefix . 'popularpostssummary` AS pps
INNER JOIN `' . $wpdb->prefix . 'posts` AS p ON pps.`postid`= p.`ID`
WHERE p.post_type = "post"
AND pps.last_viewed > DATE_SUB("' . $now . '", INTERVAL ' . $interval . ')
ORDER BY pps.`pageviews` DESC
LIMIT 4;';
echo $sql; exit;
$top4 = $wpdb->get_results( $sql, ARRAY_A );
I got
for($i = $start_date;$start_date <= $end_date;$i->modify('+1 day')) {
$i->format('Y-m-d').'<br />';
$dates = $i->format('Y-m-d');
echo $query = "
SELECT md.dish_id
, md.daydate
, d.id
, d.dish_name
, d.weight
, d.price
FROM dishes d
LEFT
JOIN menu_details md
ON d.id = md.dish_id
WHERE md.daydate = '$dates'
";
$result = mysql_query($query);
}
while($row = mysql_fetch_array($result)) {
echo 'Date: '.$row['daydate'].'Name: '.$row['dish_name'].'<br />';
}
how can i row 'dish_name' for every date on a new row.In the database there are more then 1 row with same date=
You should try to avoid running queries in loops...
Try:
$query = "SELECT md.dish_id, md.daydate, d.id, d.dish_name, d.weight, d.price
FROM dishes d
LEFT JOIN menu_details md ON (d.id = md.dish_id)
WHERE md.daydate BETWEEN '$start_date' AND '$end_date'
GROUP BY md.daydate ";
$result = mysql_query($query);
while($row = mysql_fetch_array($result)) {
echo 'Date: '.$row['daydate'].'Name: '.$row['dish_name'].'<br />';
}
What is the group by for? I think it may cause you to lose some of the results...
I am looking to run a query with query_posts that lets me look at meta_fields.
I have done this once before and achieved the result I wanted but now for some reason adding an extra field into the equation returns nothing.
The query below returns all attachments where the lottery_year is equal to $y, and obviously $y can be 2011 or earlier.
Now my next step I want to bring in another meta_field called photo_technique and give that one a value.
Question, how do I do that?
$querystr = "
SELECT $wpdb->posts.*
FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE ($wpdb->postmeta.meta_key = 'lottery_year' AND $wpdb->postmeta.meta_value = $y)
AND $wpdb->posts.post_type = 'attachment'
ORDER BY $wpdb->postmeta.meta_value ASC
LIMIT 100
";
If you whant to display posts that have either lottery_year = $y ( or ) photo_technique = $x, you could use :
$querystr = "
SELECT $wpdb->posts.*
FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE ($wpdb->postmeta.meta_key = 'lottery_year' AND $wpdb->postmeta.meta_value = $y) OR ($wpdb->postmeta.meta_key = 'photo_technique' AND $wpdb->postmeta.meta_value = $x)
AND $wpdb->posts.post_type = 'attachment'
ORDER BY $wpdb->postmeta.meta_value ASC
LIMIT 100
";
Edit
If you whant to display results that have both lottery_year = $y ( AND ) photo_technique = $x, you could use the following query :
$querystr = "
SELECT
$wpdb->posts.*
FROM
$wpdb->posts
INNER JOIN $wpdb->postmeta ON
$wpdb->posts.ID = $wpdb->postmeta.post_id
AND $wpdb->postmeta.meta_key IN ( 'lottery_year', 'photo_technique' )
AND $wpdb->postmeta.meta_value IN ( '$y', '$x' )
WHERE $wpdb->posts.post_type = 'attachment'
GROUP BY $wpdb->posts.ID
HAVING COUNT(1) = 2
ORDER BY $wpdb->postmeta.meta_value ASC
LIMIT 100
";
Edit
The last query ( the AND one ) will fail in some circumstances. For example you whant
lottery_year = $y AND photo_technique = $x, but it will allso return results that have the $x and $y switched like : lottery_year = $x AND photo_technique = $y, it realy depends when you can rely on it or not, like do you have a photo_technique that is called for example '2001' ( witch could pass as a lottery_year too ) . Please be carefull with it or ask this question on dba.stackexchange.com or wordpress.stackexchange.com .
I am wondering how I can rework this statement to exclude a certain category, ie. category id = 14
Please note that the wordpress categories are in a different table.
referenced as term_relationships and the category is term_taxonomy_id
<?php
$now = gmdate("Y-m-d H:i:s", strtotime('0 days'));
$request = $wpdb->prepare("SELECT ID, post_title, post_date, post_excerpt,LEFT(post_content,$sqllimit) AS short_post_content FROM $wpdb->posts WHERE post_status = 'publish' ");
if($hide_pass_post) $request .= "AND post_password ='' ";
if($include_pages) $request .= "AND (post_type='post' OR post_type='
else $request .= "AND post_type='post' ";
$request .= "AND post_date_gmt > '$now' ORDER BY post_date ASC LIMIT $skip_posts, $returnnum";
$posts = $wpdb->get_results($request); ?>
$request = $wpdb->prepare("SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.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.term_id = 3
AND $wpdb->term_taxonomy.term_id <> 14
AND $wpdb->term_taxonomy.taxonomy = 'category'
AND $wpdb->posts.post_type = 'post'
AND $wpdb->posts.post_status = 'publish')");