I'm trying to write a SQL update that takes part of a string and updates with part of another string (both strings already in the database).
My query looks like this, but it doesn't work :(
UPDATE wp_postmeta SET meta_value = REPLACE(meta_value,
SELECT SUBSTRING(meta_value, 1, 23) AS meta_header
FROM wp_postmeta WHERE meta_id = 8443,
SELECT SUBSTRING(meta_value, 1, 23) AS meta_header
FROM wp_postmeta WHERE meta_id = 2037)
WHERE post_id = 8443
Any ideas for how to write it?
Thanks.
Does this work?
replace into wp_postmeta (meta_id,meta_value)
select 8443,concat(SUBSTRING(meta_value,1,23),t.end)
from wp_postmeta JOIN
(select SUBSTRING(meta_value,24) as end from wp_postmeta where meta_id=8443) as t
where meta_id=2037
Solution with group_concat:
replace into wp_postmeta (meta_id,meta_value)
select 8443,group_concat(type SEPARATOR '') from
(select mem_id,substring(type,1,23) as type from wp_postmeta where mem_id=2037
UNION
select mem_id,substring(type,24) as type from wp_postmeta where mem_id=8443) as t;
Try this by joining your tables
UPDATE wp_postmeta wp1
JOIN wp_postmeta wp2 ON (wp1.meta_id =wp2.meta_id )
JOIN wp_postmeta wp3 ON (wp1.meta_id =wp3.meta_id )
SET wp1.meta_value = REPLACE(wp1.meta_value, SUBSTRING(wp2.meta_value, 1, 23) ,SUBSTRING(wp3.meta_value, 1, 23))
WHERE wp2.meta_id = 8443 AND wp3.meta_id = 2037
AND wp1.post_id = 8443
Related
I have some duplicated rows on my Wordpress wp_postmeta table. Actually hundreds of cases where old postmeta data are listed 2 or 3 times... maybe from some data import process done in the past... So I need to remove unneeded duplicate rows from wp_postmeta table, leaving just the ones with higher meta_id number... To exemplify what the wp_postmeta table looks like:
meta_id | post_id | meta_key | meta_value
155153 | 177115 | owner_img | https://www.example.com/a.jpg
176231 | 177115 | owner_img | https://www.example.com/a.jpg
193983 | 177115 | owner_img | https://www.example.com/a.jpg
Note that these are 3 metadata for the same post on wp_post table (as it has the same post_id)... so I just need to keep the latest metadata row, and delete all other instance where metadata is duplicated for each meta_key... how can I do that?
DELETE wp_postmeta.*
FROM wp_posts
INNER JOIN wp_postmeta ON wp_postmeta.post_ID = wp_posts.ID
I was able to figure it out after many research, in case anyone out there is looking for the answer...
DELETE t1 FROM wp_postmeta t1
INNER JOIN wp_postmeta t2
WHERE t1.meta_id < t2.meta_id
AND t1.meta_key = t2.meta_key
AND t1.post_id=t2.post_id;
You can do the deletion by first filtering out the lower valued meta_id
DELETE wp_posts
FROM wp_posts
JOIN wp_posts x ON x.post_ID = wp_posts.post_ID
AND wp_posts.meta_id < x.meta_id
WHERE x.post_id=wp_posts.post_id
AND x.meta_key = wp_posts.meta_key
exercise:
create table wp_posts (meta_id integer,
post_id integer,
meta_key varchar(20),
meta_value varchar(200)
);
insert into wp_posts values(155153 , 177115 , 'owner_img','https://www.example.com/a.jpg');
insert into wp_posts values(176231 , 177115 , 'owner_img' , 'https://www.example.com/a.jpg');
insert into wp_posts values(193983 , 177115 , 'owner_img' , 'https://www.example.com/a.jpg');
commit;
-- SELECT TO CHECK/VERIFY
Select distinct wp_posts.meta_id
FROM wp_posts
JOIN wp_posts x ON x.post_ID = wp_posts.post_ID
AND wp_posts.meta_id < x.meta_id
WHERE x.post_id=wp_posts.post_id
AND x.meta_key = wp_posts.meta_key
OUTPUT
meta_id
155153
176231
Delete
Delete wp_posts
FROM wp_posts
JOIN wp_posts x ON x.post_ID = wp_posts.post_ID
AND wp_posts.meta_id < x.meta_id
WHERE x.post_id=wp_posts.post_id
AND x.meta_key = wp_posts.meta_key
;
commit;
Select * from wp_posts;
OUTPUT
meta_id post_id meta_key meta_value
193983 177115 owner_img https://www.example.com/a.jpg
I've developed a query which selects events from Wordpress. I am using the where clause to select where the meta_value of the meta_key eventstartdate is after today.
The issue I'm having now is, I also want filter on a second meta_value that being from the meta_key '_VenueCity'.
I have tried aliasing the wp_postmeta table and doing a where on the meta_key but I think I'm missing a join.
This is the code that works without my additional code to get it to work. Can any one advise on how I get this to work?
SELECT
`wp_posts`.`ID` AS `EventID`,
`wp_posts`.`post_parent` AS `SeriesID`,
`wp_posts`.`post_title` AS `EventTitle`,
`wp_posts`.`post_content` AS `EventDescription`,
`wp_posts`.`post_excerpt` AS `EventSummary`,
`wp_posts`.`post_name` AS `EventSlug`,
min(`wp_postmeta`.`meta_value`) AS `EventStartDate`,
max(`tribe_event_end_date`.`meta_value`) AS `EventEndDate`,
`wp_posts`.`guid` AS `GUID`
FROM ((`wp_posts`
JOIN `wp_postmeta` ON
(
(`wp_posts`.`ID` = `wp_postmeta`.`post_id`)
))
LEFT JOIN `wp_postmeta` `tribe_event_end_date` ON
(
(
(`wp_posts`.`ID` = `tribe_event_end_date`.`post_id`) AND
(`tribe_event_end_date`.`meta_key` = '_EventEndDate')
)
))
WHERE
(
(`wp_postmeta`.`meta_key` = '_EventStartDate') AND
(`wp_posts`.`post_type` = 'tribe_events') AND
(`wp_posts`.`post_status` = 'publish') AND
(`tribe_event_end_date`.`meta_value` >= CURDATE())
)
GROUP BY
`wp_posts`.`ID`
ORDER BY
`EventStartDate`,
`wp_posts`.`post_date`;
I am not going to write your query for you but I will give an example of how to get multiple postmeta values. The power will be in the where clause to get the right values.
You should also consider what joins you want to use.
SELECT
p.post_title,
pm1.meta_value,
pm2.meta_value
FROM wp_posts as p
INNER JOIN wp_postmeta as pm1
ON p.ID = pm1.post_id
INNER JOIN wp_postmeta as pm2
ON p.ID = pm2.post_id
WHERE
pm1.meta_key = '_my_postmeta_field1'
AND
pm2.meta_key <> '_not_this_field'
I have this query:
SELECT *
FROM `wp_postmeta`
WHERE `meta_key` = '_test'
AND `post_id` IN (SELECT post_id FROM `wp_postmeta`
where meta_value = 8023)
Returns the SQL error:
Table 'wp_postmeta' is specified twice, both as a target for 'UPDATE'
and as a separate source for data
I have read other answers and attempting to add a further SELECT * FROM ( ) around the sub query but didn't help.
I assume I need some form of AS in here but can't figure out the exact code.
Can you rewrite the query in the format that won't trigger the error?
The same for this similar query:
UPDATE wp_postmeta
SET meta_value = 5.55
WHERE meta_key = '_regular_price'
AND post_id IN (
SELECT post_id
FROM wp_postmeta
WHERE meta_value = 8023
)`
You can use alias for table name
(and as suggestion in your case you can also use join instead of in )
SELECT a.*
FROM `wp_postmeta` a
inner join `wp_postmeta` b on a.`post_id = b.post_id
where a.`meta_key` = '_test'
and b.meta_value = 8023
In update you could use a join with subselect for circumvent the limits due to update actions on the same table
UPDATE wp_postmeta a
inner join (
SELECT post_id
FROM wp_postmeta
WHERE meta_value = 8023
) t on a.`post_id = t.post_id and a.`meta_key` = '_test'
SET meta_value = 5.55
SELECT * FROM wp_postmeta as wp_out
WHERE wp_out.meta_key = '_test'
AND wp_out.post_id IN
( SELECT wp_in.post_id
FROM wp_postmeta as wp_in
where wp_in.meta_value = 8023)
Although this is not a good answer, but it is effective, ha ha..
SELECT *
FROM wp_postmeta
WHERE meta_key = '_test'
AND post_id IN (SELECT GROUP_CONCAT(post_id) FROM wp_postmeta
where meta_value = 8023)
The SELECT query posted in the question is equivalent to this one:
SELECT p1.*
FROM `wp_postmeta` p1
INNER JOIN `wp_postmeta` p2 ON p1.`post_id` = p2.`post_id`
WHERE p1.`meta_key` = '_test'
AND p2.`meta_value` = 8023
In fact, if some conditions are met, the MySQL engine converts the original SELECT query into a query similar to this as an optimization.
This SELECT query can be easily changed into the desired UPDATE query:
UPDATE `wp_postmeta` p1
INNER JOIN `wp_postmeta` p2 ON p1.`post_id` = p2.`post_id`
SET p1.`meta_values` = 5.55
WHERE p1.`meta_key` = '_test'
AND p2.`meta_value` = 8023
I am trying to construct a select statement. The table structure is shown below. I am basically looking to select the three fields on the left table along with the meta_values of the right hand side table that have a meta_key of responsible_service and responsible_officer. These meta_values may or may not exist.
My awful attempt looks like this.
SELECT
`wp_posts`.`ID`,
`wp_posts`.`post_content`,
`wp_posts`.`post_title`
FROM(
`wp_posts`
INNER JOIN `wp_postmeta` ON (`wp_posts`.`ID` = `wp_postmeta`.`post_id`),
(Select `wp_postmeta`.meta_value where`wp_postmeta`.meta_key='responsible_officer') as Responsible Officer),
(Select `wp_postmeta`.meta_value where `wp_postmeta`.meta_key='responsible_service') as Responsible Service ),
The result should look like this
This will give you 1 or more rows per wp_posts.ID depending on how many 'responsible_officer' and 'responsible_service' are found. If none are found meta_key and meta_value will be null
SELECT
`wp_posts`.`ID`,
`wp_posts`.`post_content`,
`wp_posts`.`post_title`,
max(case `wp_postmeta`.meta_key
when 'responsible_officer' then `wp_postmeta`.meta_value end) as responsible_officer,
max(case `wp_postmeta`.meta_key
when 'responsible_service' then `wp_postmeta`.meta_value end) as responsible_service
FROM
`wp_posts`
LEFT JOIN `wp_postmeta` ON `wp_posts`.`ID` = `wp_postmeta`.`post_id`
AND `wp_postmeta`.meta_key in ('responsible_officer', 'responsible_service')
group by `wp_posts`.`ID`,
`wp_posts`.`post_content`,
`wp_posts`.`post_title`;
Check this also:
select postmeta.meta_value, posts.ID, posts.`post_content`,
posts.`post_title` from `wp_posts` posts join `wp_postmeta` postmeta on posts.ID = postmeta.post_id where postmeta.meta_key IN ('responsible_officer', 'responsible_service')
SELECT
`wp_posts`.`ID`,
`wp_posts`.`post_content`,
`wp_posts`.`post_title`
FROM `wp_posts`
JOIN `wp_postmeta` ON (`wp_posts`.`ID` = `wp_postmeta`.`post_id`)
where `wp_postmeta`.meta_key in ('responsible_officer', 'responsible_service')
When i run the below query in mysql it took 78 sec to display record. Is there other way to write this query. Here is my
mysql query -> "
select distinct nuqta1.post_id from wp_postmeta as nuqta1
inner join wp_postmeta as nuqta2 on (nuqta1.post_id = nuqta2.post_id)
inner join wp_postmeta as nuqta4 on (nuqta1.post_id = nuqta4.post_id)
inner join wp_postmeta as nuqta5 on (nuqta1.post_id = nuqta5.post_id)
inner join wp_postmeta as nuqta6 on (nuqta1.post_id = nuqta6.post_id)
inner join wp_postmeta as nuqta7 on (nuqta1.post_id = nuqta7.post_id)
inner join wp_postmeta as nuqta8 on (nuqta1.post_id = nuqta8.post_id)
inner join wp_postmeta as nuqta9 on (nuqta1.post_id = nuqta9.post_id)
inner join wp_postmeta as nuqta10 on (nuqta1.post_id = nuqta10.post_id)
inner join wp_postmeta as nuqta11 on (nuqta1.post_id = nuqta11.post_id)
inner join wp_postmeta as nuqta12 on (nuqta1.post_id = nuqta12.post_id)
where (nuqta2.meta_key = 'checkin' and nuqta2.meta_value LIKE '%10/31/2012%')
and (nuqta4.meta_key = 'guests' and nuqta4.meta_value ='1')
and (nuqta5.meta_key = 'roomtype' and nuqta5.meta_value LIKE '%Entire home/apt%')
and (nuqta6.meta_key = 'price' and cast(nuqta6.meta_value as signed) BETWEEN '10' and '99999')
and (nuqta7.meta_key = 'amenities' and nuqta7.meta_value LIKE '%Wireless Internet%')
and (nuqta8.meta_key = 'amenities' and nuqta8.meta_value LIKE '%TV%')
and (nuqta9.meta_key = 'amenities' and nuqta9.meta_value LIKE '%Kitchen%')
and (nuqta10.meta_key = 'amenities' and nuqta10.meta_value LIKE '%Wireless Internet%')
and (nuqta11.meta_key = 'amenities' and nuqta11.meta_value LIKE '%TV%')
and (nuqta12.meta_key = 'amenities' and nuqta12.meta_value LIKE '%Kitchen%')
and 1=1 order by nuqta1.post_id asc
".
And and i am using wordpress table wp_postmeta to run this query
You have a lot of LIKE '%whatever%' clauses in this query. Each of these clauses necessarily causes a full table scan of wp_postmeta. It's actually pretty good that you got them done in less than ten seconds each.
If you know more about your meta_value column's values, so you can use LIKE 'whatever%' (getting rid of the leading % wildcard term) you'll speed things up a lot.
Also it's not clear why you have nuqta10, nuqta11, nuqta12. Those seem to search for the same stuff as 7,8,9. Considering the cost of the searches, you might consider eliminating those.
Try using Fulltext Search
What you'll do is something like
SELECT
*
FROM
tableName
WHERE
MATCH ( columnName ) AGAINST ( 'Keyword1', 'Keyword2', 'Keyword3' )