SQL Search if contains keyword random - php

I working on my search function and I have an Issue
My query:
$query = " SELECT p.ID, p.post_title
FROM $posts p
LEFT JOIN $postmeta pm ON (pm.post_id = p.ID AND pm.meta_key = '_sku')
WHERE p.post_type = 'product'
AND (
p.ID LIKE '%$keywords%' OR
p.post_title LIKE '%$keywords%' OR
IF(pm.meta_value IS NULL, 0, pm.meta_value LIKE '%$keywords%')
)
ORDER BY p.post_title";
In the column post_title I have a value like Remy Martin XO
Now you can search on Remy or Martin or Remy Matin and there are results.
But if you search on Martin Remy there are no results.
What I tried so far:
I changed the query and replaced the LIKE to CONTAINS but now I have no results on any search
$query = " SELECT p.ID, p.post_title
FROM $posts p
LEFT JOIN $postmeta pm ON (pm.post_id = p.ID AND pm.meta_key = '_sku')
WHERE p.post_type = 'product'
AND (
p.ID LIKE '%$keywords%' OR
--> CONTAINS(p.post_title, '$keywords') <-- OR
IF(pm.meta_value IS NULL, 0, pm.meta_value LIKE '%$keywords%')
)
ORDER BY p.post_title";
Who can help me with this?

Please replace your line with this line. Hopefully it will work.
CONTAINS(p.post_title, '$keywords',1) > 0
If it is my SQL then use INSTR(str,substr). You can search this Syntex you will get lots of example.

Related

Php mysql search - Search not working if with plural and singular

If I search "sales order" it's fetching "sales order" and "sales orders" in results. It's fetching the result with "s" also.
But if I search "sales orders" it's fetching "sales orders" only but I want "sales order" will also fetch.
I am using php mysql query.
SELECT DISTINCT * FROM wp_posts as p
inner join wp_postmeta as pm on pm.post_id = p.ID
where (p.post_type = 'abc' or p.post_type = 'xyz')
and p.post_title LIKE '%sales order%'
or (pm.meta_key = 'xyzkeyword' and pm.meta_value LIKE '%sales order%')
GROUP by p.ID
ORDER BY p.id DESC
Try with this without "%"
p.post_title LIKE 'sales order'
You can also try like this
and (p.post_title LIKE '%sales order%' OR p.post_title LIKE '%sales orders%' )
I hope this will solve your issue.
I am not much sure about this query but you can check as
SELECT DISTINCT * FROM wp_posts as p
inner join wp_postmeta as pm on pm.post_id = p.ID
where (p.post_type = 'abc' or p.post_type = 'xyz')
and p.post_title LIKE '%sales%' AND p.post_title LIKE '%order%'
or (pm.meta_key = 'xyzkeyword' and pm.meta_value LIKE '%sales order%')
GROUP by p.ID
ORDER BY p.id DESC
OR
SELECT DISTINCT * FROM wp_posts as p
inner join wp_postmeta as pm on pm.post_id = p.ID
where (p.post_type = 'abc' or p.post_type = 'xyz')
and p.post_title LIKE '%sales%order%'
or (pm.meta_key = 'xyzkeyword' and pm.meta_value LIKE '%sales order%')
GROUP by p.ID
ORDER BY p.id DESC
use MySQL Full text search,check if FULLTEXT indexes are there
SELECT DISTINCT * FROM wp_posts as p
inner join wp_postmeta as pm on pm.post_id = p.ID
where (p.post_type = 'abc' or p.post_type = 'xyz')
match (p.post_title) against ('sales order')
or (pm.meta_key = 'xyzkeyword' and pm.meta_value LIKE '%sales order%')
GROUP by p.ID
ORDER BY p.id DESC

Wordpress sql query not working as expected

I have term parent called 'product_parent' that has three childs terms :
child_term_1 (id=2) (5 posts)
child_term_2 (id=3) (3 posts)
child_term_3 (id=4) (10 posts)
each post has **meta_key price ** (string) and i have to filter posts by price:
0 to 50, 50 to 100 and 100 +
this query works well (i can get 15 products):
SELECT DISTINCT p.ID FROM wp_posts as p
LEFT JOIN wp_postmeta as p ON price.post_id = p.ID
LEFT JOIN wp_relationships as t ON t.object_id = p.ID
WHERE p.post_type = 'product' AND post_status = 'publish'
AND t.term_taxonomy_id IN ('2', '3', '4')
AND p.meta_key = 'price'
AND p.meta_value LIKE '%50-100%'
OR p.meta_value LIKE '%100+%'
GROUP BY p.ID
but if i add one filter :
SELECT DISTINCT p.ID FROM wp_posts as p
LEFT JOIN wp_postmeta as p ON price.post_id = p.ID
LEFT JOIN wp_relationships as t ON t.object_id = p.ID
WHERE p.post_type = 'product' AND post_status = 'publish'
AND t.term_taxonomy_id IN ('2', '3', '4')
AND p.meta_key = 'price'
AND p.meta_value LIKE '%0-50%'
OR p.meta_value LIKE '%50-100%'
OR p.meta_value LIKE '%100+%'
GROUP BY p.ID
This returns "many posts" that not in term_taxonomy_id specified.
Someone could clarify me please? i don't want to use Wp_Query(), i just want to use sql.
Thanks for your help.
you use the same alias
then duplicate alias
try:
SELECT DISTINCT p.ID FROM wp_posts as p
LEFT JOIN wp_postmeta as pm ON pm.post_id = p.ID
LEFT JOIN wp_relationships as r ON r.object_id = p.ID
WHERE p.post_type = 'product' AND p.post_status = 'publish'
AND r.term_taxonomy_id IN ('2', '3', '4')
AND pm.meta_key = 'price'
AND pm.meta_value LIKE '%0-50%'
OR pm.meta_value LIKE '%50-100%'
OR pm.meta_value LIKE '%100+%'
GROUP BY p.ID

Combine 2 Queries with different number of rows

I have a query that connects to a wordpress db and returns some posts.
In order to get the image for each of these posts i run another query inside a php foreach loop
The problem is that running the second query inside the foreach loop is extremely slow and i need another way to merge these 2 queries into 1.
The first query
SELECT pm. * , p.*
FROM wp_posts p
JOIN wp_postmeta pm ON pm.post_id = p.ID
WHERE pm.meta_key = 'accommodation_location_post_id'
AND pm.meta_value
IN (
SELECT pi.ID
FROM wp_posts pi
WHERE pi.post_title LIKE '%Cyprus%')
Based on the returned post ids, i need for each of these ids
the featured image.
This query does this job, but only for 1 id only.
The second query
SELECT wp_posts.guid
FROM wp_posts
WHERE wp_posts.ID =
(Select wp_postmeta.meta_value
FROM wp_postmeta
WHERE wp_postmeta.meta_key =
'_thumbnail_id' AND wp_postmeta.post_id = 'The id of each post')
I need a query to return all the posts alongside with its images.
I really don't understand your data structure, but try this query
select
t1.*, t2.guid
from (
SELECT pm. * , p.*
FROM wp_posts p
JOIN wp_postmeta pm ON pm.post_id = p.ID
WHERE pm.meta_key = 'accommodation_location_post_id'
AND pm.meta_value IN (
SELECT pi.ID
FROM wp_posts pi
WHERE pi.post_title LIKE '%Cyprus%'
)
) t1
left join (
select
p2.guid, pm2.post_id
from
wp_posts p2
join wp_postmeta pm2 on
pm2.meta_value = p2.ID
and pm2.meta_key = '_thumbnail_id'
) t2 on t2.post_id = t1.ID

Select rows as columns for wordpress post meta

WordPress's wp_postmeta table has all the additional fields for a post but they are in rows so it's easy to add more.
However, now I want to query for all the fields of all the posts lets say, I obviously want those fields in a column and not a row.
This is my query that I am running
SELECT p.post_title,
m.meta_value,
m.meta_key
FROM wp_posts p
JOIN wp_postmeta m
ON p.id = m.post_id
WHERE p.id = 72697;
This will give me all the meta_values and their respective meta keys as columns. But I need the meta keys values as columns and meta values as rows
For example a meta_key could be additional_description and it's value could be What's up
So I need something like this
SELECT p.post_title, additional_description
FROM wp_posts p
JOIN wp_postmeta m
ON p.id = m.post_id
WHERE p.id = 72697;
I need it as a column. I also need all of the posts and not a specific one, but whenever I remove the where it just doesn't query (I have lots of posts, that could be an issue).
Here is some sample data and how I want the results to show up
wp_postmeta table
meta_key post_id meta_key meta_value
1 5 total_related 5
2 5 updated 0
3 5 cricket 1
4 8 total_related 8
5 8 updated 1
6 8 cricket 0
wp_post table
id post_title other things I dont care about
5 This is awesome
8 This is more awesome
wp_post id is related to post_id on wp_postmeta table
Result wanted
post_title total_related updated cricket
This is awesome 5 0 1
This is more awesome 8 1 0
What about something like this?
SELECT p.post_title, m1.meta_value as 'total_related', m2.meta_value as 'updated', m3.meta_value as 'cricket'
FROM wp_posts p
LEFT JOIN wp_postmeta m1
ON p.id = m1.post_id AND m1.meta_key = 'total_related'
LEFT JOIN wp_postmeta m2
ON p.id = m2.post_id AND m2.meta_key = 'updated'
LEFT JOIN wp_postmeta m3
ON p.id = m3.post_id AND m3.meta_key = 'cricket'
And since you aren't looking for a specific post you should be able to do this.
If you want to query specific post_types you can try something like this
SELECT p.post_title, m1.meta_value as 'total_related', m2.meta_value as 'updated', m3.meta_value as 'cricket'
FROM wp_posts p
LEFT JOIN wp_postmeta m1
ON p.id = m1.post_id AND m1.meta_key = 'total_related'
LEFT JOIN wp_postmeta m2
ON p.id = m2.post_id AND m2.meta_key = 'updated'
LEFT JOIN wp_postmeta m3
ON p.id = m3.post_id AND m3.meta_key = 'cricket'
WHERE p.post_type = 'my_custom_post_type';
Try that:
select post_title ,
MAX(CASE WHEN `meta_key`='total_related' THEN meta_value END)as 'total_related',
MAX(CASE WHEN `meta_key` = 'updated' THEN meta_value END) as 'updated' ,
MAX(CASE WHEN `meta_key` = 'cricket' THEN meta_value END) as 'cricket'
FROM wp_posts p
JOIN wp_postmeta m ON p.id = m.post_id
GROUP BY p.id
There are several approaches.
Here's an example of one way to get the specified result, using correlated subqueries in the SELECT list:
SELECT p.post_title
, ( SELECT m1.meta_value
FROM wp_post_metadata m1
WHERE m1.meta_key = 'total_related'
AND m1.post_id = p.id
ORDER BY m1.meta_key LIMIT 1
) AS `total_related`
, ( SELECT m2.meta_value
FROM wp_post_metadata m2
WHERE m2.meta_key = 'updated'
AND m2.post_id = p.id
ORDER BY m2.meta_key LIMIT 1
) AS `updated`
, ( SELECT m3.meta_value
FROM wp_post_metadata m3
WHERE m3.meta_key = 'cricket'
AND m3.post_id = p.id
ORDER BY m3.meta_key LIMIT 1
) AS `cricket`
FROM wp_posts p
WHERE p.id IN (5,8)
There are several other approaches, each with its own advantages and drawbacks.
There's a somewhat related question I referenced in a comment on the question. That question illustrates several approaches, but omits a correlated subquery approach.)
Here's how I did this dynamically - this procedure builds a SQL statement for every postmeta key for a given post type and then runs the "pivot" query for you:
This isn't the fastest query, and we use it only for migration and deep dives into data, but it does the job.
Note that this temporarily resets the max length of the concat function so you can build a large SQL statement:
CREATE PROCEDURE `wp_posts_pivot`(IN post_type_filter varchar(50))
BEGIN
/* allow longer concat */
declare max_len_original INT default 0;
set max_len_original = ##group_concat_max_len;
set ##group_concat_max_len=100000;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(pm.meta_key = ''',
meta_key,
''', pm.meta_value, NULL)) AS `',
meta_key,
'`'))
INTO #sql FROM
wp_posts p
INNER JOIN
wp_postmeta AS pm ON p.id = pm.post_id
WHERE
p.post_type = post_type_filter;
SET #sql = CONCAT('SELECT p.id
, p.post_title
, ', #sql, '
FROM wp_posts p
LEFT JOIN wp_postmeta AS pm
ON p.id = pm.post_id
where p.post_type=\'',post_type_filter,'\'
GROUP BY p.id, p.post_title');
/* reset the default concat */
set ##group_concat_max_len= max_len_original;
/*
select #sql;
*/
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
You can then call this with a simple call such as this one, which will select a single row for each 'page' post type along with all meta values:
call wp_posts_pivot('page');

sql statement for querying wp posts from specific category

i want to query wordpress posts from specific category parent but the problem is that there is no such column on wp_posts table so i need to join but my skills on the sql is not good so i need some help ,
here is the query i use for querying posts
$query = "SELECT c.*
FROM {$wpdb->prefix}posts p,
{$wpdb->prefix}comments c WHERE p.ID = c.comment_post_ID AND c.comment_approved > 0 AND p.post_type = 'product' AND p.post_status = 'publish' AND
p.comment_count > 0 ORDER BY ".$order_by." LIMIT 0, ". $number_of_comments;
}
and here is some snippet i found for joining term_taxonomy_id
$answer = $wpdb->get_results("SELECT post_title, post_content, term_taxonomy_id FROM wp_posts LEFT JOIN wp_term_relationships ON wp_posts.ID = wp_term_relationships.object_id WHERE SUBSTRING(post_title,1,1)='T' AND term_taxonomy_id=6");
the proplem i can't seem to figure how to use this example on my query neither thinking of simpler solutions so i can query from specific parent category , thanks for your help
here is the query i used and worked ..
$query = "SELECT c.*
FROM
{$wpdb->prefix}comments c ,
{$wpdb->prefix}posts p JOIN $wpdb->term_relationships TR
ON p.ID=TR.object_id
JOIN $wpdb->term_taxonomy T
ON TR.term_taxonomy_id=T.term_taxonomy_id
JOIN $wpdb->terms TS
ON T.term_id = TS.term_id
WHERE p.ID = c.comment_post_ID AND c.comment_approved > 0 AND p.post_type = 'product' AND p.post_status = 'publish' AND
p.comment_count > 0 AND T.taxonomy = 'product_cat' AND T.term_id='$term_cat' ORDER BY ".$order_by." LIMIT 0, ". $number_of_comments;
}
you would be looking at something like this:
global $wpdb;
$wpdb->show_errors();
$ur=$wpdb->get_results( $wpdb->prepare(
"
SELECT *
FROM $wpdb->posts P
JOIN $wpdb->term_relationships TR
ON P.ID=TR.object_id // identify link column
JOIN $wpdb->term_taxonomy T
ON TR.term_taxonomy_id=T.term_taxonomy_id
JOIN $wpdb->terms TS
ON T.term_id = TS.term_id
WHERE P.post_type = %d // use wild chars (define below, this one equals carmarket)
AND P.post_status = %f
AND T.taxonomy= %s
",
'carmarket',
'publish',
'carmake'
) );
$wpdb->print_error();
var_dump($ur);

Categories