NOT LIKE does not work with JOIN in wordpress - php

I have this sql query in wordpress with php
$sql = "SELECT last_update.post_id FROM {$wpdb->postmeta} last_update";
$sql .= " JOIN {$wpdb->posts} AS post ON last_update.post_id = post.ID";
$sql .= $wpdb->prepare(" WHERE {$time} - last_update.meta_value > {$ttl} AND last_update.meta_key = %s", Importer::META_LAST_UPDATE);
if (SyncConfig::getInstance()->option('published_only'))
$sql .= " AND post.post_status = 'publish'";
$sql .= $wpdb->prepare(" ORDER BY last_update.meta_value ASC LIMIT %d", self::getProductLimit());
$product_ids = $wpdb->get_col($sql);
shuffle($product_ids);
error_log(print_r( $product_ids, true ));
What I want is to skip the results with a "NOT LIKE" for the wildcard result "Product data not found"
Normally I would do something like this
$sql = "SELECT last_update.post_id FROM {$wpdb->postmeta} last_update";
$sql .= " JOIN {$wpdb->posts} AS post ON last_update.post_id = post.ID";
//QUITAR PRODUCTOS CON DATA NOT FOUND
$sql .= " JOIN {$wpdb->postmeta} AS _ety_product_info ON last_update.post_id = _ety_product_info.post_id";
$sql .= $wpdb->prepare(" WHERE {$time} - last_update.meta_value > {$ttl} AND last_update.meta_key = %s", Importer::META_LAST_UPDATE);
//QUITAR PRODUCTOS CON DATA NOT FOUND
$sql .= " AND _ety_product_info.meta_value NOT LIKE '%Product data not found%'";
if (SyncConfig::getInstance()->option('published_only'))
$sql .= " AND post.post_status = 'publish'";
$sql .= $wpdb->prepare(" ORDER BY last_update.meta_value ASC LIMIT %d", self::getProductLimit());
$product_ids = $wpdb->get_col($sql);
shuffle($product_ids);
error_log(print_r( $product_ids, true ));
But it gives wrong data.
The strangest thing is that if I remove the "NOT LIKE" and just leave it on "LIKE" it works delivering the expected result if the "_ety_product_info" column contains the value "Product data not found"
What am I doing wrong?
I want to exclude with "NOT LIKE" but it doesn't work.
Apparently this error only happens when I do the "JOIN"
Note: To identify the changes made in the original code with the edited one, just search for: //QUITAR PRODUCTOS CON DATA NOT FOUND
The final query
$sql it would be this:
SELECT last_update.post_id
FROM wp_postmeta last_update
JOIN wp_posts AS post ON last_update.post_id = post.ID
JOIN wp_postmeta AS _ety_product_info ON last_update.post_id = _ety_product_info.post_id
WHERE 1659698743 - last_update.meta_value > 86400
AND last_update.meta_key = '_ety_last_update'
AND _ety_product_info.meta_value NOT LIKE '%Product data not found%'
AND post.post_status = 'publish'
ORDER BY last_update.meta_value ASC LIMIT 17
I also tried this but it didn't work.
$wild = '%';
$find = 'Product data not found';
$like = $wild . $wpdb->esc_like( $find ) . $wild;
$sql .= $wpdb->prepare(" AND _ety_product_info.meta_value NOT LIKE %s", $like);

For what it's worth, the query you showed us says NOT LIKE 'Product data not found'. I guess you want it to say NOT LIKE '%Product data not found%' with the % wildcard characters.
And, try using LEFT JOIN and putting the NOT LIKE in your ON-condition. In general for readability with these key/value metadata tables it's a good idea to put the key selector in the ON condition. It doesn't matter to the logic for JOINs but it does for LEFT JOINs.
SELECT last_update.post_id
FROM wp_postmeta last_update
JOIN wp_posts AS post
ON last_update.post_id = post.ID
AND last_update.meta_key = '_ety_last_update'
LEFT JOIN wp_postmeta AS _ety_product_info
ON last_update.post_id = _ety_product_info.post_id
AND _ety_product_info.meta_value NOT LIKE '%Product data not found%'
WHERE 1659698743 - last_update.meta_value > 86400
AND post.post_status = 'publish'
ORDER BY last_update.meta_value ASC
LIMIT 17
This might work for you: JOIN suppresses the rows from the first table that don't match the second table, but LEFT JOIN keeps them.
This is guesswork. I don't know what other keys are in your metadata tables.

Related

Get products IDs by _sale_price_dates_to before now in Woocommerce

I try to get the post_ids from postmeta where the _sale_price_dates_to are less the now. And I did something like this:
global $wpdb;
$publishid = $wpdb->get_results('SELECT meta_value FROM ' . $wpdb->postmeta . ' WHERE meta_key="_sale_price_dates_to" and meta_value<=' .time().'') or die("Error: Cannot create object");
But it doesn't work. Maybe because the _sale_price_dates_to has format longtext not date. how to change it in the query?
But It's not over. I want to add the condition that the products have to be published then I have to join:
$publishid = $wpdb->get_results('SELECT meta_value FROM ' . $wpdb->postmeta . 'join' . $wpdb->posts . ' ON wp_posts.ID = wp_postmeta.post_id WHERE wp_postmeta.meta_key="_sale_price_dates_to" and wp_postmeta.meta_value<=' .time().' and wp_posts.post_status="publish" ') or die("Error: Cannot create object");
But because of the first problem, I don't know it works.
Update: Setting up the right time zone in the code
Try the following to make a functional SQL query using WPDB to get the Post IDs where post meta _sale_price_dates_to timestamp is less the now time stamp:
global $wpdb;
// Set the correct time zone (http://php.net/manual/en/timezones.php)
date_default_timezone_set('Europe/Paris');
// An array of IDs
$results = $wpdb->get_col("
SELECT p.ID
FROM {$wpdb->prefix}posts AS p
JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
WHERE p.post_status = 'publish'
AND pm.meta_key = '_sale_price_dates_to'
AND pm.meta_value <= '".time()."'
AND pm.meta_value != ''
");
// Raw Output (array of post IDs)
print_r($results);
Tested and works.
meta_value != '' is needed to avoid Post IDs with empty values to be queried.

UNION 2 sql queries - wp_posts vs wp_terms - PHP, WORDPRESS

I have a page where I'm displaying all taxonomy categories and all posts/pages. There I need to have ajax pagination so that my page won't load ages (or even not load). So I've built the pagination via sql query and now need to get both terms and posts with sql query, then union them so that my pagination will work properly and count including them all.
Here is my code:
$sql1 = "SELECT * FROM wp_term_taxonomy LEFT JOIN wp_terms ON (wp_term_taxonomy.term_id =
wp_terms.term_id) WHERE wp_term_taxonomy.taxonomy = 'product-category'";
$sql2 = "SELECT * FROM wp_posts WHERE (post_type = 'products' OR post_type = 'page')
AND (post_status = 'publish' OR post_status = 'suspended') AND ID NOT IN
(231, 236, 1070, 1245) order by post_title ASC";
$sql = $sql1." UNION ".$sql2;
$query = $sql . " limit " . $start . "," . $resultPerPage->perpage;
$list = $db_handle->runBackendQuery($query);
Above returns me following errors:
Warning: mysqli_fetch_object() expects parameter 1 to be mysqli_result, boolean given in .../dbcontroller.php on line 29
Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in
.../dbcontroller.php on line 38
I think I can join such 2 different things. Is there anything I'm missing?
The error could happen because you have some error in your query for avoid this
You should select the same number of column and with corresponding data type so try avoiding select all (*) and use explicit select column you should use a sintax like eg:
$sql1 = "SELECT col_a1, col_a2, col_a3 FROM wp_term_taxonomy LEFT JOIN wp_terms ON (wp_term_taxonomy.term_id =
wp_terms.term_id) WHERE wp_term_taxonomy.taxonomy = 'product-category'";
$sql2 = "SELECT col_b1, col_b2, col_b3 FROM wp_posts WHERE (post_type = 'products' OR post_type = 'page')
AND (post_status = 'publish' OR post_status = 'suspended') AND ID NOT IN
(231, 236, 1070, 1245) order by post_title ASC";
$sql = $sql1." UNION ".$sql2;
$query = $sql . " limit " . $start . "," . $resultPerPage->perpage;
$list = $db_handle->runBackendQuery($query);

select to multiply tables for print mysqli_num_rows

Good evening all.
Is there one that will give me an example of how to make such a script here:
I try to make a while combining 2 different tables in my database to get correct mysqli_num_rows.
Like this:
$Querypris ("SELECT * FROM" wpd2_posts` where post_status = 'wc-failed' and select * From `wpd2_postmeta` where meta_key = '_ order_total' and meta_value> 300 ')
$Num_rowspris = mysqli_num_rows ($ query price);
So I want to get mysqli_num_rows from all those who are post_status = 'wc-completed' but also meta_value> 300
Hope you understand what I mean :)
Well, your php code will not work like this. At least variable names must be consistent.
You should use JOIN clause in your sql statement. I suppose, there is a column like "post_id" in both tables.
$query_price = "SELECT * FROM wpd2_posts JOIN wpd2_postmeta USING (post_id) WHERE post_status = 'wc-completed' AND meta_key = '_order_total' AND meta_value > 300";
$result = mysqli_query($connection, $query_price);
$number_of_rows = mysqli_num_rows($result);
UPDATE:
If names of the columns, referring to ID of the post, are different in those tables, for example "ID" in "wpd2_posts" and "post_id" in "wpd2_postmeta", then you should use a following query:
SELECT * FROM wpd2_posts p JOIN wpd2_postmeta pm
ON p.ID = pm.post_id
WHERE p.post_status = 'wc-completed'
AND pm.meta_key = '_order_total' AND pm.meta_value > 300
UPDATE: removed space from '_ order_total'. changed to '_order_total'
SELECT * FROM wpd2_posts,wpd2_postmeta where wpd2_posts.post_status = wc-completed and wpd2_postmeta.meta_key = _ order_total and wpd2_postmeta.meta_value > 300 and wpd2_posts.fk=wpd2_postmeta.fk
this thing might not work for not having foreign key
SELECT * FROM wpd2_posts CROSS JOIN wpd2_postmeta where wpd2_posts.post_status = wc-completed and wpd2_postmeta.meta_key = _ order_total and wpd2_postmeta.meta_value > 300
Its better to use foreign keys.
hope this will help
If your site is WordPress then use this:
global $wpdb;
$sql="SELECT * FROM wpd2_posts pt INNER JOIN wpd2_postmeta pmt ON pmt.post_id = pt.ID WHERE pt.post_status = 'wc-completed' AND pmt.meta_key = '_order_total' AND pmt.meta_value>300";
$results = $wpdb->get_results($sql, ARRAY_A );
$num_rowspris = count($results);
// OR ---------
$results = $wpdb->query($sql);
$num_rowspris = $results->num_rows;
else :
Note: $conn is your DB connection
$results = mysqli_query($conn, $sql);
$num_rowspris = mysqli_num_rows($results);

Wordpress Custom Query Against Taxonomy Term and Post Metadata

I have this custom query I need to do that will check against both post_metadata values and taxonomy terms. I'm using code that I modified from Wordpress's codex, but it is returning zero results consistently. Is there a mistake I've made? (UPDATED: shows where it is being loaded into a variable first)
global $wpdb;
$querystr = "
SELECT * FROM $wpdb->posts
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_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
WHERE $wpdb->terms.name = '" . $service . "'
AND $wpdb->term_taxonomy.taxonomy = 'Services'
AND $wpdb->postmeta.meta_value = '" . $county . "'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
AND $wpdb->postmeta.meta_key = 'order'
ORDER BY $wpdb->postmeta.meta_value ASC";
$pageposts = $wpdb->get_results($querystr, OBJECT);
I would suggest logging the actual string that is executed (save this select to a variable and log the variable, then pass the variable to the wpdb query). Once you have the sql, you can more easily troubleshoot it (or post it here for further assistance).

MySQL Query Not Working PHP

I have a query I'm trying to build so that I can filter by car brand. But if a certain session variable exists, it'll ask for an extra part to be added to the query which is basically limiting the results to the logged in branch. Here's the query:
$query_AUCTION = "SELECT *
FROM at_auction AS a
JOIN at_brands AS b ON a.aCarBrandID = b.bid
ORDER BY b.brand $orderx";
... now this works but where can I add a:
"WHERE bid = '{$bid}'"? ...or a... "AND bid = '{$bid}'";
It brings up an error.
insert your where clauses BEFORE your order by
$query_AUCTION = "SELECT * FROM at_auction AS a JOIN at_brands AS b ON a.aCarBrandID = b.bid WHERE bid = '{$bid}' ORDER BY b.brand $orderx";
Use a generic WHERE 1=1 and if you want to insert additional condition:
$query_AUCTION = "SELECT *
FROM at_auction AS a
JOIN at_brands AS b ON a.aCarBrandID = b.bid
WHERE 1=1 ";
if ($bid > 0)
$query_AUCTION .= " AND bid = '{$bid}' ";
$query_AUCTION .= " ORDER BY b.brand $orderx";
try this :
$query_AUCTION = "SELECT *
FROM at_auction AS a
JOIN at_brands AS b ON ( b.bid = a.aCarBrandID ) ";
if( isset( $_SESSION['bid'] ) )
{
$query_AUCTION.= " WHERE b.bid = '".$_SESSION['bid']."'";
}
$query_AUCTION.= " ORDER BY b.brand $orderx";

Categories