Increase query performance - mysql

I'm trying to optimize this query:
SELECT post_id
FROM wp_postmeta
WHERE meta_key = 'passenger_group_id'
AND meta_value in (SELECT post_id
FROM wp_postmeta
WHERE meta_key = 'group_event' AND meta_value = '14608')
AND post_id IN (SELECT post_id
FROM wp_postmeta
WHERE meta_value='Cancelled')
AND post_id NOT IN (SELECT ID
FROM wp_posts
WHERE post_status='trash')
Any help would be greatly appreciated.

you can use EXISTS clause alone and add NOT IN condition can be made NOT EXISTS
select wp1.post_id
from wp_postmeta wp1
WHERE meta_key = 'passenger_group_id'
and exists ( select 1 FROM
wp_postmeta wp2
where ( (wp2.meta_key = 'group_event' AND wp2.meta_value = '14608' ) or wp2.meta_value ='Cancelled' )
and wp2.post_id = wp1.meta_value
)
and not exists ( select 1 from
wp_posts p
on p.id = wp1.post_id
and p.post_status = 'trash')
)

Related

delete with 2 join get error - mysql

I'm trying to run this delete query in MYSQL (via phpMyAdmin) ANd I keep getting this error :
DELETE
p,pm
from wp_posts p
inner join wp_postmeta pm on pm.post_id = p.id
where p.id in (SELECT MIN( id ) AS min_id
FROM wp_posts inner join wp_postmeta on (wp_posts.ID=wp_postmeta.post_id and meta_key = 'old_id')
WHERE post_type = 'post'
GROUP BY meta_value
HAVING COUNT( * ) > 1)
any idea why ?
Looking to your code
You don't should use as in subselect for IN clause
DELETE p, pm
from wp_posts as p
inner join wp_postmeta as pm on pm.post_id = p.id
where p.id in (SELECT MIN( id )
FROM wp_posts
inner join wp_postmeta on (wp_posts.ID=wp_postmeta.post_id
and meta_key = 'old_id')
WHERE post_type = 'post'
GROUP BY meta_value
HAVING COUNT( * ) > 1)

SQL Subquery (select data from three tables)

I'm using this query to get data from mysql. Can it be improved? It takes around 0.2s for each query...
I found some other way such as left join but I can't get all data with one query.
Or do I need to use two queries?
Select p.id, p.post_date, p.post_content, p.post_title, p.post_name, p.guid
for loop -> likes_count, dislikes_count, post_views_count, rate where post_id = p.id?
SELECT p.id, p.post_date, p.post_content, p.post_title, p.post_name, p.guid,
(SELECT guid FROM wp_posts WHERE id = (SELECT meta_value FROM wp_postmeta WHERE post_id = p.id AND meta_key = "_thumbnail_id")) AS thumbnail_url,
(SELECT GROUP_CONCAT(DISTINCT term_taxonomy_id) FROM wp_term_relationships WHERE object_id = p.id) AS term_taxonomy_id,
(SELECT meta_value FROM wp_postmeta WHERE post_id = p.id AND meta_key = "likes_count" LIMIT 1) AS likes_count,
(SELECT meta_value FROM wp_postmeta WHERE post_id = p.id AND meta_key = "dislikes_count" LIMIT 1) AS dislikes_count,
(SELECT meta_value FROM wp_postmeta WHERE post_id = p.id AND meta_key = "post_views_count" LIMIT 1) AS post_views_count,
(SELECT meta_value FROM wp_postmeta WHERE post_id = p.id AND meta_key = "rate" LIMIT 1) AS rate
FROM wp_posts AS p INNER JOIN wp_term_relationships AS t ON p.id = t.object_id
WHERE p.post_status="publish"
AND p.ping_status="open"
AND t.term_taxonomy_id = ? GROUP BY p.id LIMIT ?,?
[EDIT-1]
[Table structure]1
[EDIT-2]
The Output
{"id":11111,"post_date":"2016-01-02T05:46:58.000Z","post_content":"contenttttttt","post_title":"titleeeee","post_name":"postname","guid":"1255322","thumbnail_url":"thumb1957.jpg","term_taxonomy_id":"7","likes_count":"1","dislikes_count":"1","post_views_count":"538","rate":"50"}

MySql query not returning correct data

I have a Wordpress MySQL database that I need to create a custom query for using SQL. I am trying to return the current event (post) where the "date_start" value is less than the current day and the "date_end" value is greater than or equal to the current day. I know that there is a data record that should be returned butnothing is being returned when I try to do a search on both "date_start" and "date_end"
This is my old SQL statement:
select ID, post_name, meta_id, meta_key, meta_value from wp_posts inner join wp_postmeta on wp_posts.ID = wp_postmeta.post_id and ((meta_key='date_end' and meta_value >= CURDATE() + interval 1 day) and (meta_key='date_start' and meta_value < CURDATE())) where post_type='programs' order by meta_value
The new SQL statement:
SELECT
ID,
post_name,
(SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_start') AS 'date_start',
(SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_end') AS 'date_end'
FROM wp_posts
WHERE
post_type = 'programs'
AND ((CURDATE() >= (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_start'))
AND (CURDATE() <= (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_end')))
ORDER BY `wp_posts`.`ID` ASC
And the date that is being returned is:
ID post_name date_start date_end
1221 culture-analytics 20160307 20160610
2446 culture-analytics-tutorials 20160308 20160311
I have also tried where the date_start and date_end portion of the inner join was in the WHERE clause.
IMPORTANT: wp_postmeta is a Many To 1 schema, whereas 'date_start' and 'date_end' are separate records but both point to the same PostID
What seems to be the problem.
You have two conflicting constraints on meta_key. Your query expects meta_key to equal both "date_start" and "date_end" at the same time.
Maybe try something like this:
SELECT
ID,
post_name,
meta_id,
(SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_start') AS 'date_start',
(SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_end') AS 'date_end'
FROM wp_posts
WHERE
post_type = 'programs'
AND (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_start') < CURDATE()
AND (SELECT meta_value FROM wp_postmeta WHERE wp_postmeta.post_id = ID AND meta_key = 'date_end') >= (CURDATE() + INTERVAL 1 DAY)
ORDER BY 4
I don't have access to a Wordpress database so I haven't run it but it might work...
#obe caught the core problem with your original query in his answer; but I would solve it with an additional join rather than four subqueries:
SELECT ID, post_name, meta_id
, beginMeta.meta_key As beginKey, endMeta.meta_key AS endKey
, beginMeta.meta_value AS beginDate
, endMeta.meta_value AS endDate
FROM wp_posts
INNER JOIN wp_postmeta AS endMeta
ON wp_posts.ID = endMeta.post_id
AND endMeta.meta_key='date_end'
AND endMeta.meta_value >= CURDATE() + interval 1 day
INNER JOIN wp_postmeta AS beginMeta
ON wp_posts.ID = beginMeta .post_id
AND beginMeta.meta_key='date_start'
AND beginMeta.meta_value < CURDATE()
WHERE post_type='programs'
ORDER BY beginDate, endDate
;
Edit: This assumes (post_id, meta_key) combinations are unique in wp_postmeta.

SQL Multiple WHERE IN

I am trying to select the ID from a wp_posts table where I need to do 3 conditions.
Is the ID matching with the post_id from the wp_postmeta table where the meta_key = 'gtp_analytics_client_id' and the meta_value is not empty.
Is the ID matching with the post_id from the wp_postmeta table where the meta_key = 'gtp_conversion_uploaded' and the meta_value is not equal to 1.
Is the ID matching with the post_id from the wp_postmeta table where the meta_key = 'gtp_lead_revenue' and the meta_value is not empty.
I am a beginner with SQL. This is what I have now, but I cannot use multiple IN's. So I think I need to do it another way.
SELECT ID
FROM wp_posts
WHERE ID IN (SELECT post_id
FROM wp_postmeta
WHERE meta_key = 'gtp_analytics_client_id' AND meta_value != '')
AND IN (SELECT post_id
FROM wp_postmeta
WHERE meta_key = 'gtp_conversion_uploaded' AND meta_value != 1)
AND IN (SELECT post_id
FROM wp_postmeta
WHERE meta_key = 'gtp_revenue' AND meta_value != '')
I get the following error:
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 'IN (SELECT post_id FROM wp_postmeta WHERE meta_key = 'gtp_conversion_uploaded' A' at line 4
The and is not part of the in operator, it is three separate in operators, so you need the first operand (ID) for all of them:
SELECT ID
FROM wp_posts
WHERE ID IN ( ... )
AND ID IN ( ... )
AND ID IN ( ... )
You could also write that as three joins:
SELECT
p.ID
FROM
wp_posts p
INNER JOIN wp_postmeta m1 ON m1.post_id = p.ID AND m1.meta_key = 'gtp_analytics_client_id' AND m1.meta_value != ''
INNER JOIN wp_postmeta m2 ON m2.post_id = p.ID AND m2.meta_key = 'gtp_conversion_uploaded' AND m2.meta_value != 1
INNER JOIN wp_postmeta m3 ON m3.post_id = p.ID AND m3.meta_key = 'gtp_revenue' AND m3.meta_value != ''
When it can be either of the 3 cases
SELECT ID
FROM wp_posts
WHERE ID IN (SELECT post_id
FROM wp_postmeta
WHERE (meta_key = 'gtp_analytics_client_id' AND meta_value != '')
OR (meta_key = 'gtp_conversion_uploaded' AND meta_value != 1)
OR (meta_key = 'gtp_revenue' AND meta_value != '')
)
SELECT p.ID
FROM wp_posts p
JOIN wp_postmeta m on p.id = m.post_id
group by p.id
having sum(m.meta_key = 'gtp_analytics_client_id' AND m.meta_value != '') > 0
and sum(m.meta_key = 'gtp_conversion_uploaded' AND m.meta_value != 1) > 0
and sum(m.meta_key = 'gtp_revenue' AND m.meta_value != '') > 0

applying a query as a filter on another query's result MySQL

I have 2 queries as below,
A SELECT DISTINCT meta_value, meta_id FROM `wp_postmeta` WHERE `meta_key`='destination';
B SELECT ID FROM wp_posts WHERE post_status = 'publish';
What I want is something like this,
SELECT meta_value FROM A WHERE A.meta_id = B.ID;
try this
SELECT A.meta_value, A.meta_id
FROM `wp_postmeta` A
INNER JOIN wp_posts B
ON meta_id = id
WHERE A.`meta_key`= 'destination'
AND B.post_status = 'publish'
GROUP BY A.meta_value
SELECT DISTINCT
meta_value
FROM `wp_postmeta` wpm,
wp_posts wp
WHERE wp.ID = wpm.meta_id
AND wpm.`meta_key` = 'destination'
AND wp.post_status = 'publish';