MySQL LIKE operator behaving like = operator - mysql

It seems MySQL's LIKE operator behaves like a = operator.
The following MySQL query returns the expected result (1 entry):
$meta_key = '_locality';
$meta_value = 'The Hague';
$post_ids = $wpdb->get_col( $wpdb->prepare(
"
SELECT post_id
FROM $wpdb->postmeta
WHERE meta_key = %s
AND meta_value LIKE %s
",
$meta_key,
$meta_value
) );
But the following, with only part of the original meta_value, returns an empty array:
$meta_key = '_locality';
$meta_value = 'The';
$post_ids = $wpdb->get_col( $wpdb->prepare(
"
SELECT post_id
FROM $wpdb->postmeta
WHERE meta_key = %s
AND meta_value LIKE %s
",
$meta_key,
$meta_value
) );
What am I doing wrong here?

Please read mysql pattern matching syntax carefully: http://dev.mysql.com/doc/refman/5.0/en/pattern-matching.html . You lose '%' for LIKE matching:
$meta_key = '_locality';
$meta_value = '%The Hague%';
$post_ids = $wpdb->get_col( $wpdb->prepare(
"
SELECT post_id
FROM $wpdb->postmeta
WHERE meta_key = %s
AND meta_value LIKE %s
",
$meta_key,
$meta_value
) );

Related

How do I combine 2 SELECT statements where the result

How do I combine 2 SELECT statements where the result of the first select is used in the WHERE of the second SELECT
Below is the code I am using right now:
$order_id = 7655;
$first = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM wp_postmeta WHERE meta_key = '_ticket_order' AND meta_value = %d", $order_id ) );
if ( $first ) {
$second = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM wp_postmeta WHERE meta_key = '_ticket_event' AND post_id = %d", $first ) );
}
echo $second;
You could try using a join between the two queries
$second = $wpdb->get_var( $wpdb->prepare("SELECT b.meta_value
FROM wp_postmeta a
INNER JOIN wp_postmeta b ON a.post_id = b.post_id
WHERE a.meta_key = '_ticket_order' AND a.meta_value = %d", $order_id ) );

How to change a query in mysql so it retrieve 30 rows randomly

I'd like to change this query in my WordPress plugin so that it retrieves 30 random rows out of 100.
$query = $wpdb->prepare("
SELECT
p.*, qq.quiz_id, qq.question_order AS order
FROM
{$wpdb->posts} p
INNER JOIN
{$wpdb->prefix}learnpress_quiz_questions qq ON p.ID = qq.question_id
WHERE
qq.quiz_id IN (" . join( ',', $format ) . ")
AND
p.post_status = %s
", $args );
I've changed it to this but it still does not work. Could any body help me ,please?
SELECT
p.*, qq.quiz_id, qq.question_order AS order
FROM
{$wpdb->posts} p
INNER JOIN
{$wpdb->prefix}learnpress_quiz_questions qq ON p.ID = qq.question_id
WHERE
qq.quiz_id IN (" . join( ',', $format ) . ")
AND
p.post_status = %s
ORDER BY
RAND() LIMIT 30
Change your sort to something like this:
order by RAND() * 30
or if you have an integer id:
order by RAND() * id

Why does $wpdb->get_result() return value different from the get_posts() from add_filter()

I'm new to Wordpress programming, I want to make a custom code, the problem here is:
I got the different values from almost identical sql queries. The first one from $wpdb->get_results() function and the another one from the add_filter() function.
So why I would do this? it's because I have a database, where the items have different currency. So I would like to sort the price after change it to the default currency which is USD in my case. (I already have the function tho), so the problem is I don't get the same post ID even though it's already similar
Here is the query I wrote on $wpdb
$results = $wpdb->get_results("
SELECT
wp_posts.ID AS id,
price.meta_value AS price_value,
currency.meta_value AS currency_value
FROM
wp_posts
INNER JOIN " . $wpdb->postmeta . " ON (" . $wpdb->posts . ".ID = wp_postmeta.post_id)
INNER JOIN " . $wpdb->postmeta . " AS currency ON (" . $wpdb->posts . ".ID = currency.post_id AND currency.meta_key = 'month_currency')
INNER JOIN " . $wpdb->postmeta . " AS price ON (" . $wpdb->posts . ".ID = price.post_id AND price.meta_key = 'month_price')
WHERE
1=1
AND ((wp_postmeta.meta_key = 'monthly' AND wp_postmeta.meta_value = 'Y'))
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
GROUP BY
wp_posts.ID
LIMIT
0, 12
");
And the result is:
ID: 40168
ID: 39832
ID: 40346
ID: 40846
ID: 42200
ID: 39687
ID: 39467
ID: 29605
ID: 32620
ID: 32773
ID: 35175
ID: 17
There are a lot of code here between them
And this one is from the add_filter function:
$mam_global_fields = ', price.meta_value';
$mam_global_join = "
INNER JOIN " . $wpdb->postmeta . " AS currency ON (" . $wpdb->posts . ".ID = currency.post_id AND cur.meta_key = 'month_currency')
INNER JOIN " . $wpdb->postmeta . " AS price ON (" . $wpdb->posts . ".ID = price.post_id AND price.meta_key = 'month_price')";
$mam_global_orderby = "FIELD(" . $wpdb->posts . ".ID" . $order_id . ")";
And here is the query that created by the add_filter()
SELECT
SQL_CALC_FOUND_ROWS DISTINCT wp_posts.*,
price.meta_value
FROM
wp_posts
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS currency ON (wp_posts.ID = currency.post_id AND currency.meta_key = 'month_currency')
INNER JOIN wp_postmeta AS price ON (wp_posts.ID = price.post_id AND price.meta_key = 'month_price')
WHERE
1=1
AND ((wp_postmeta.meta_key = 'monthly' AND wp_postmeta.meta_value = 'Y'))
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
GROUP BY
wp_posts.ID
ORDER BY
FIELD(wp_posts.ID, 40168, 39832, 40346, 40846, 42200, 39687, 39467, 29605, 32620, 32773, 35175, 17)
LIMIT
0, 12
The ID order already correct but the query showing another post which is not the exact ID value like the $wpdb, so why it's happened?
Or is there any better way that I can use instead this one? I appreciate any kind of help, thank you

I want the the database query result to output the record of last seven days (referral_users )

get_results( "SELECT u.ID,
( SELECT meta_value FROM " . $wpdb -> prefix . "usermeta WHERE meta_key = 'first_name' AND user_id = u.ID ) AS firstname,
( SELECT meta_value FROM " . $wpdb -> prefix . "usermeta WHERE meta_key = 'last_name' AND user_id = u.ID ) AS lastname,
( SELECT COUNT( user_id ) FROM " . $wpdb -> prefix . "usermeta WHERE meta_key = 'user_parent' AND meta_value = u.ID ) AS referral_users
FROM
" . $wpdb -> prefix . "users AS u
WHERE
( SELECT COUNT( user_id ) FROM " . $wpdb -> prefix . "usermeta WHERE meta_key = 'user_parent' AND meta_value = u.ID ) > 0
ORDER BY referral_users DESC LIMIT 10 OFFSET 0" );

Wordpress SQL - Multiple WHERE clauses

Ok it has been a while since I last wrote an sql query. I have the following query
$user_search->query_where =
str_replace('WHERE 1=1',
"WHERE 1=1 AND {$wpdb->users}.ID IN (
SELECT {$wpdb->usermeta}.user_id FROM $wpdb->usermeta
WHERE {$wpdb->usermeta}.meta_key = 'select_team_leader'
AND {$wpdb->usermeta}.meta_value = {$user_leader})",
$user_search->query_where
);
I want to add an OR statement like
OR {$wpdp->usermeta}.user_id = {$user_leader}
Do I need to use an inner join for this ? thanks
No you don't need to use an extra join you just have to organize your query to look for either user id or meta_value
$user_search->query_where =
str_replace('WHERE 1=1',
"WHERE 1=1 AND {$wpdb->users}.ID IN (
SELECT {$wpdb->usermeta}.user_id FROM $wpdb->usermeta
WHERE {$wpdb->usermeta}.meta_key = 'select_team_leader'
AND
(
{$wpdb->usermeta}.meta_value = {$user_leader}
OR {$wpdp->usermeta}.user_id = {$user_leader}
)
)",
$user_search->query_where
);
So above query will look for meta_value is equal to provided value ie. {$user_leader} or user_id is equal to {$user_leader} but whatever matches meta_key should be select_team_leader
Edit from comments
$user_search->query_where =
str_replace('WHERE 1=1',
"WHERE 1=1 AND {$wpdb->users}.ID IN (
SELECT {$wpdb->usermeta}.user_id FROM $wpdb->usermeta
WHERE (
{$wpdb->usermeta}.meta_key = 'select_team_leader'
AND {$wpdb->usermeta}.meta_value = {$user_leader}
)
OR {$wpdp->usermeta}.user_id = {$user_leader}
)",
$user_search->query_where
);