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);
Related
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.
I am executing this query with core cron by custom Wordpress plugin:
// MAKE SQL CALL
$SQL = "SELECT ".$wpdb->prefix."postmeta.post_id FROM ".$wpdb->prefix."postmeta
INNER JOIN ".$wpdb->prefix."posts ON (".$wpdb->prefix."posts.ID = ".$wpdb->prefix."postmeta.post_id )
WHERE ".$wpdb->prefix."postmeta.meta_key = '".$core_admin_values['listing_expiration']['key']."'
AND ".$wpdb->prefix."posts.post_status = 'publish'
AND ".$wpdb->prefix."postmeta.post_id = (SELECT ".$wpdb->prefix."postmeta.post_id FROM ".$wpdb->prefix."postmeta WHERE ".$wpdb->prefix."postmeta.meta_key = 'listing_status' AND ".$wpdb->prefix."postmeta.meta_value != 1)
AND ".$wpdb->prefix."posts.post_type = '".$core_admin_values['listing_expiration']['taxonomy']."_type'
AND DATE(".$wpdb->prefix."postmeta.meta_value) < DATE(NOW())";
$expired_listings = (array)$wpdb->get_results($SQL);
But return this error:
FastCGI sent in stderr: "PHP message: Database error of WordPress Subquery returns more than 1 row for SELECT
How to solve this? I tried some solutions by similar problems here in Stack, but it still fails.
For the sake of legibility I reformatted your query.
SELECT
postmeta.post_id
FROM
postmeta
INNER JOIN posts
ON (posts.ID = postmeta.post_id )
WHERE
postmeta.meta_key = '".$core_admin_values['listing_expiration']['key']."'
AND posts.post_status = 'publish'
AND postmeta.post_id =
(
SELECT
postmeta.post_id
FROM
postmeta
WHERE
postmeta.meta_key = 'listing_status'
AND postmeta.meta_value != 1
)
AND posts.post_type = '".$core_admin_values['listing_expiration']['taxonomy']."_type'
AND DATE(postmeta.meta_value) < DATE(NOW())";
I suspect your issue stems from the subquery in your where clause.
SELECT
postmeta.post_id
FROM
postmeta
WHERE
postmeta.meta_key = 'listing_status'
AND postmeta.meta_value != 1
And that this chunk is returning more than one result. If you want to match against more than one result, change from "=" to "in" like so:
AND postmeta.post_id in
(
SELECT
postmeta.post_id ...
)
try to add LIMIT on subquery
// MAKE SQL CALL
$SQL = "SELECT ".$wpdb->prefix."postmeta.post_id FROM ".$wpdb->prefix."postmeta
INNER JOIN ".$wpdb->prefix."posts ON (".$wpdb->prefix."posts.ID = ".$wpdb->prefix."postmeta.post_id )
WHERE ".$wpdb->prefix."postmeta.meta_key = '".$core_admin_values['listing_expiration']['key']."'
AND ".$wpdb->prefix."posts.post_status = 'publish'
AND ".$wpdb->prefix."postmeta.post_id = (SELECT ".$wpdb->prefix."postmeta.post_id FROM ".$wpdb->prefix."postmeta WHERE ".$wpdb->prefix."postmeta.meta_key = 'listing_status' AND ".$wpdb->prefix."postmeta.meta_value != 1 LIMIT 1)
AND ".$wpdb->prefix."posts.post_type = '".$core_admin_values['listing_expiration']['taxonomy']."_type'
AND DATE(".$wpdb->prefix."postmeta.meta_value) < DATE(NOW())";
$expired_listings = (array)$wpdb->get_results($SQL);
similar problem several years after, but, in my case, I wasn't able to find the query to make the change, so, I decided to remove the warning message (because it was just a warning) and the way that I used for did that was adding this lines to the wp-config.php file:
ini_set('display_errors','Off');
ini_set('error_reporting', E_ALL );
define('WP_DEBUG', false);
define('WP_DEBUG_DISPLAY', false);
Regards!
I currently have a query that checks whether a certain word is found in the array values.
$imploded = implode("','",$company_array);
$query = "SELECT *
FROM $wpdb->usermeta
WHERE meta_key='company'
AND meta_value IN ('".$imploded."')";
The $company_array contains different values.
I want to add another WHERE clause but don't know how.
It should check on the users role:
SELECT*
FROM $wpdb->usermeta
WHERE meta_key = 'wp_capabilities'
AND meta_value = 'subscriber'
Maybe some sort of join queries? I have no clue.
==== Sample data and expected output ====
This is my current query
$query = "SELECT *
FROM $wpdb->usermeta
WHERE meta_key='company'
AND meta_value IN ('".$imploded."')";
I want to add the following query
SELECT*
FROM $wpdb->usermeta
WHERE meta_key = 'wp_capabilities'
AND meta_value = 'subscriber'
The first query loads a list of users that work for a certain company.
The problem is................
Crap. I just realised something while writing this.
The problem was that the administrator is also listed in the list of users. I wanted him out of the results.
The users are listed based upon their value in the company field. But if that is empty the admin isn't listed anywhere.
Your WHERE clause needs to be
WHERE (meta_key='company' AND meta_value IN ('".$imploded."'))
OR (meta_key = 'wp_capabilities' AND meta_value = 'subscriber')
try like this
$query = "SELECT *
FROM $wpdb->usermeta
WHERE (meta_key='company'
AND meta_value IN ('".$imploded."')) or (meta_key = 'wp_capabilities' and meta_value = 'subscriber')";
I think you required below. Note the () with OR for your both where clauses.
$query = "SELECT *
FROM $wpdb->usermeta
WHERE ( meta_key='company' AND meta_value IN ('".$imploded."')")
OR (meta_key = 'wp_capabilities' AND meta_value = 'subscriber');
I have a query like this:
$query = "SELECT a.sender_id,
a.recipient_id,
a.form_id, due_date,
a.completed,
f.name,
p.priority,
u.first_name,
u.last_name,
SUM(a.completed) as completed_sum
FROM form_assignments a
JOIN forms f ON (form_id = f.id)
JOIN users u ON (sender_id = u.id)
JOIN priorities p ON (priority_id = p.id)
WHERE recipient_id = '{$_SESSION['user_id']}'
ORDER BY due_date ASC";
And a while loop like this:
$assignment_count = (mysqli_num_rows($result));
$assignments_row = array();
while ($row = mysqli_fetch_array($result)) {
$sender = $row['first_name'] . ' ' . $row['last_name'];
$form_id = $row['form_id'];
$form_name = $row['name'];
$priority = $row['priority'];
$due_date = date('m/d/Y', strtotime($row['due_date']));
$completed = $row['completed'];
$not_done = $assignment_count - $row['completed_sum'];
}
And it's only returning one row. It seems my SUM(a.completed) as completed_sum is causing the issues because the query worked fine before I added it, but I want to add up all the values in completed to use in my $not_done variable.
Can anyone help clarify what I'm doing wrong?
When you use an aggregate function like SUM, all the results will be aggregated into one row unless you use a GROUP BY clause to segregate them. But it looks to me like you don't need a SUM in the first place. Your loop is subtracting this value from a total, so you just need the value from each row -- when you subtract them all you'll have subtracted the total. So just select a.completed rather than SUM(a.completed).
For $not_done, you need to initialize it before the loop:
$not_done = $assignment_count;
Then during the loop you should do a running subtraction:
$not_done -= $row['completed'];
Try this query :
SELECT
a.sender_id,
a.recipient_id,
a.form_id,
a.due_date,
a.completed,
f.name,
p.priority,
u.first_name,
u.last_name,
b.completed as completed_sum
FROM
form_assignments AS a
LEFT JOIN (
SELECT form_id,SUM(completed) FROM form_assignments GROUP BY form_id
) AS b ON (a.form_id = b.form_id)
LEFT JOIN forms AS f ON (form_id = f.id)
LEFT JOIN users AS u ON (sender_id = u.id)
LEFT JOIN priorities AS p ON (priority_id = p.id)
WHERE
recipient_id = '{$_SESSION['user_id']}'
ORDER BY due_date ASC
I am attempting to count comments on a particular page with the following problematic sql query:
$query = "SELECT * FROM `comments` WHERE is_approved = '1' AND page_id = '943'"
$query = mysql_query($query);
$total = mysql_num_rows($query);
echo $total;
the problem is it is outputting 0 and not 2.
The tables are as follows:
pages:
id:1 page_id:943
id:2 page_id:978
id:3 page_id:977
comments:
id:2 page_id:1 "hello"
id:3 page_id:1 "great"
id:4 page_id:3 "super"
So really the original query should be getting each comment's true page_id from the page_id as set in the pages tables, as joined by comments.page_id = pages.id
What would the final code look like to either make that join, and/or get that count? Thank you.
Try:
SELECT c.* FROM `comments` c
JOIN `pages` p on c.page_id = p.id
WHERE c.is_approved = '1' AND p.page_id = '943'
"SELECT * FROM comments, pages WHERE comments.page_id = pages.id AND is_approved = '1' AND comments.page_id = '943'"
Try using:
SELECT count(*) as cnt
FROM `comments` c join pages p on c.page_id = p.id
WHERE c.is_approved = '1' AND p.page_id = '943'
It seems like a very poor database design to have two columns with the same name in different tables that mean different things. You should probably change the name of pages.page_id to something else.
And, this returns the count directly, so you can read the value from the row. If you just want the count, there is no reason to return all the matching rows.
no join is needed:
$query = "SELECT * FROM `comments` WHERE is_approved = '1' AND WHERE page_id IN (SELECT id WHERE page_id = '943')"
$query = mysql_query($query);
$total = mysql_num_rows($query);
echo $total;
ofcourse i would suggest a count statement if you do not need/use the data:
$query = "SELECT COUNT(*) as total FROM `comments` WHERE is_approved = '1' AND WHERE page_id IN (SELECT id WHERE page_id = '943')"
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
$total = $row['total'];
echo $total;