how to use the "DELETE" in mysql with COUNT and INNER JOIN? - mysql

I'm starting in mysql, and I wonder how can I do to remove the result of the SELECT below, thank you all!
SELECT ID,post_name,meta_value, guid, COUNT( meta_value )
FROM wp_postmeta
INNER JOIN wp_posts
WHERE wp_postmeta.post_id = wp_posts.ID AND wp_postmeta.meta_value >100
GROUP BY meta_value
HAVING COUNT( meta_value ) >1

You can first select and create a array or you can directly put this query with delete query using IN clause.
DELETE from wp_posts
WHERE ID IN (
SELECT ID
FROM wp_posts
INNER JOIN wp_postmeta
WHERE wp_postmeta.post_id = wp_posts.ID AND wp_postmeta.meta_value >100
GROUP BY meta_value
HAVING COUNT( meta_value ) >1)
If you set foreign key with postmeta colum post_id as on delete cascade then data from this table will automatically remove.
Otherwise please consider to create unique array of post ids and postmeta ids. And use two separate delete query with IN clause.

Related

Replace mysql column data to onther column with Match ID

Hello I have a WordPress database just updated to my site to a new theme and my Product specification is missing in new theme I try to find and found new theme using a different table column to show the specification so I have to replace product specifications in the new column.
Following the original data
Table Name: wp_postmeta
SELECT
wp_postmeta.post_id,
wp_postmeta.meta_value,
wp_postmeta.meta_key
FROM
wp_postmeta
WHERE
wp_postmeta.meta_key = '_specifications'
ORDER BY
wp_postmeta.post_id
ASC
I want to replace above data in following table with matching ID
Table Name: wp_posts
SELECT
wp_posts.ID,
wp_posts.post_content
FROM
wp_posts
ORDER BY
wp_posts.ID
ASC
You can update the table wp_posts by joining it to your first query.
update wp_posts p inner join (
select post_id, meta_value
from wp_postmeta
where meta_key = '_specifications'
) m on m.post_id = p.id
set p.post_content = m.meta_value

MySQL query stalling - is there a more efficient solution for this MySQL Query?

SELECT post_title,
count(*) AS c
FROM wp_posts
WHERE post_type = "product"
GROUP BY post_title
HAVING c > 1
ORDER BY c DESC
runs no problem, returns result in < 1 sec. Yet
select * from wp_posts where post_title in (
select post_title from wp_posts WHERE post_type = "product"
group by post_title having count(*) > 1
)
hangs up.
Yet they are fundamentally the same query except for the fact that in the second query I'm trying to pull out the entire record rather than just the post_title.
Have I erred? Is there a more efficient way to achieve the equivalent?
Edit: EXPLAIN query and SHOW CREATE TABLE wp_posts has been appended for your information.
you could avoid the IN clause on the subquery and use an inner join
select a.*
from wp_posts a
INNER JOIN (
select post_title
from wp_posts
WHERE post_type = "product"
group by post_title
having count(*) > 1
) t ON t.post_title = a.post_title
this should be more performant
The most efficient way to write this query is probably using exists . . . assuming wp_posts has a primary key:
select p.*
from wp_posts p
where p.post_type = 'product' and
exists (select 1
from wp_posts p2
where p2.post_title = p.post_title and
p2.post_type = p.post_type and
p2.id <> p.id
);
For performance, yu want an index on wp_posts(post_type, title, id).

how to get better performance, with not in query

here is my custom sql query ;
SELECT id,
post_title,
post_content,
comment_count,
post_date,
post_status,
post_name
FROM wp_posts
WHERE post_type = 'post'
AND post_status = 'publish'
AND id NOT IN (SELECT DISTINCT post_id
FROM wp_postmeta
WHERE meta_key = 'visible_headlane'
AND meta_value = 'On')
AND id NOT IN (SELECT DISTINCT post_id
FROM wp_postmeta
WHERE meta_key = 'visible_homepage'
AND meta_value = 'On')
ORDER BY post_date DESC
LIMIT 11, 32
i can not use, LIMIT in NOT IN Query so, there is any way to use, or limit SELECT DISTINCT sql query, or any idea ?
Note : I need to optimise this query because, it takes so long , like a slow query.
Thanks.
Switch to NOT EXISTS( SELECT 1 FROM ... ) -- this variation does not need to compute the entire list of things; it only needs to check for the absence. LEFT JOIN .. ON .. IS NULL is also more efficient.
Furthermore, the standard schema for wp_postmeta is quite inefficient; see my suggestions.
Meanwhile, keep it as two tests, unlike the suggestion by 'holder'.
The EXISTS would look something like
AND NOT EXISTS ( SELECT 1 FROM wp_postmeta
WHERE post_id = wp_posts.id
AND meta_key = 'visible_headlane'
AND meta_value = 'On' )
which would make good use of the PRIMARY KEY(post_id, meta_key) that I recommend.
(Is it really 'headlane', not 'headline'?)
Maybe something like this as jarlh suggested
SELECT
ID,post_title,post_content,comment_count,post_date,post_status,post_name
FROM wp_posts t1
left join (
SELECT DISTINCT post_id from wp_postmeta
WHERE meta_key IN ('visible_headlane','visible_homepage') AND meta_value = 'On' ) t2 on t1.ID = t2.post_id
WHERE post_type = 'post'
AND post_status = 'publish'
AND t2.post_id is null
ORDER BY post_date DESC
LIMIT 11, 32

how to use value from main query in sub query

Im trying to run a sub-query that based on one of the main query values but i always get 0 as VALUE.
This is my query :
SELECT ID,(
SELECT COUNT( * )
FROM `post_meta`
WHERE `post_id`
IN (
SELECT `ID`
FROM `wp_posts`
WHERE `post_title` = posts.ID
)
) AS counter
FROM wp_posts;
if i run only the sub-query with id number instead of posts.ID it returns a good value.
I do believe a simple join in the sub query will get you the correct COUNT:
SELECT posts.ID,
(
SELECT COUNT(*)
FROM post_meta
INNER JOIN wp_posts ON wp_posts.ID = post_meta.post_ID
WHERE wp_posts.post_title = posts.ID
) AS counter
FROM posts;
The problem was fixed by giving the table a custom name so i can use it when im going in two layers this is how the code look after the change :
SELECT ID,(
SELECT COUNT( * )
FROM `post_meta`
WHERE `post_id`
IN (
SELECT `ID`
FROM `wp_posts`
WHERE `post_title` = my_posts.ID
)
) AS counter
FROM wp_posts as my_posts;
Linger you beat me to it but I was going to suggest leaving out the subquery altogether if I can guess what the structure looks like.
SELECT ID, COUNT(*) AS count FROM wp_posts
INNER JOIN post_meta ON wp_posts.ID = post_meta.post_id
WHERE wp_posts.ID = post_title
GROUP BY ID
OR
SELECT COUNT(*) AS count FROM wp_posts
INNER JOIN post_meta ON wp_posts.ID = post_meta.post_id
WHERE wp_posts.ID = post_title

Getting multiple values in multiple rows from multiple tables in MySQL

I'm using WordPress. I want to get everything from the wp_posts table and two values from the postmeta table.
The "wp_postmeta" has the columns "post_id", "meta_key", and "meta_value".
So far, I'm able to get one of the "meta_value":
SELECT wp_post.*, $wpdb->postmeta.meta_value AS votes
FROM wp_posts
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
WHERE post_type='post'
AND wp_postmeta.meta_key = 'votes'
However, I also want to get another "meta_value" with the same "post_id" but a different "meta_key". How can I extend this query to the "meta_value"?
If you don't want multiple rows per post, you can do this by having multiple joins:
SELECT wp_post.*, metavotes.meta_value AS votes, metaother.meta_value AS other
FROM wp_posts
INNER JOIN wp_postmeta metavotes
ON ( wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'votes')
INNER JOIN wp_postmeta metaother
ON ( wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = 'other')
WHERE post_type='post'
(this assumes there is always exactly 1 row for each piece of metadata in wp_postmeta. I'm not familiar enough with wordpress to know whether this is the case. If metadata is optional, use LEFT OUTER JOIN's instead. If you can have multiple, what kind of output do you want?)
How about adding your additional meta_key to the query with the IN clause. Let's say it's the string value foo that you want to add:
SELECT wp_post.*, $wpdb->postmeta.meta_value AS votes
FROM wp_posts
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
WHERE post_type='post'
AND wp_postmeta.meta_key IN ('votes', 'foo');
Maybe try something like this:
SELECT wp_posts.*, wp_postmeta.meta_value, wp_postmeta.meta_key
FROM wp_posts INNER JOIN wp_postmeta ON(wp_posts.ID = wp_postmeta.post_id)
WHERE wp_posts.post_type='post'
AND wp_postmeta.meta_key IN ('votes', ...)