MYSQL select column value when two rows have same condition - mysql

I need get value if two rows have same value. I need get post_id one field 145 in output.
Should i use JOIN or not? Or maybe some simpler/faster way to do this?
But this is not correct one...But i need someting like this, when barcode and _sku values are SAME.
SELECT post_id
FROM wp_postmeta
WHERE meta_key = 'barcode' = '_sku' AND meta_value = '123';
Getting error and checking just barcode field...
Warning: #1292 Truncated incorrect DECIMAL value: '_sku'

Since MySQL 8.0 you can use INTERSECT:
SELECT post_id
FROM wp_postmeta
WHERE meta_key = 'barcode' AND meta_value = '123'
INTERSECT
SELECT post_id
FROM wp_postmeta
WHERE meta_key = '_sku' AND meta_value = '123';
https://sqlize.online/sql/mysql80/d0a7123a10d11065d9f0609044c70d35/
Another way is use GROUP BY and HAVING:
SELECT post_id
FROM wp_postmeta
WHERE meta_key IN ('barcode', '_sku') AND meta_value = '123'
GROUP BY post_id
HAVING COUNT(DISTINCT meta_key) = 2;
https://sqlize.online/sql/mysql80/594f4b262c55c10d4958f3bc54c7353b/
SELECT post_id
FROM wp_postmeta
WHERE
meta_key IN ('barcode')
AND meta_value = '123'
AND EXISTS (SELECT post_id FROM wp_postmeta pm WHERE meta_key IN ('_sku')
AND meta_value = '123' AND pm.post_id = wp_postmeta.post_id)
;

Related

MySql - Pivot Table

I'm trying to pull some data out of the wp_postmeta table which is basically a series of key/value pairs tied to a numeric post_id. As such, when I try to extract various values for a post, this is what I get:
This is the current query I'm using to get that output:
select post_id,meta_key,meta_value from wp_postmeta
where meta_key in ('_sku','_length','_width','_height')
and post_id in (
select post_id from wp_postmeta
where meta_value in ('28-005080','28-005287')
)
order by post_id DESC
What I'm trying to do is format the information like this:
I've tried to look at the MySql pivot table examples, but I'm not sure if they quite fit this specific scenario. Frankly, I don't know where to start with accomplishing this task.
You can use conditional aggregation:
select post_id,
max(case when meta_key = '_sku' then meta_value end) as sku,
max(case when meta_key = '_length' then meta_value end) as length,
max(case when meta_key = '_width' then meta_value end) as width,
max(case when meta_key = '_height' then meta_value end) as height
from wp_postmeta
where
meta_key in ('_sku','_length','_width','_height')
and post_id in (select post_id from wp_postmeta where meta_value in ('28-005080','28-005287'))
group by post_id
order by post_id desc
Actually, we might be able to replace the subquery in the where clause with a having clause:
select post_id,
max(case when meta_key = '_sku' then meta_value end) as sku,
max(case when meta_key = '_length' then meta_value end) as length,
max(case when meta_key = '_width' then meta_value end) as width,
max(case when meta_key = '_height' then meta_value end) as height
from wp_postmeta
group by post_id
having max(meta_value in ('28-005080','28-005287')) = 1
order by post_id desc

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

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.

Wordpress mysql Query

I'm trying to make a mysql query which select all the posts from wp_posts and select the post_title and post_content from it and then select the table wp_postmeta and show the meta_value where meta_key is equal with "_wp_attached_file".
I've tried doing this:
SELECT post_title, post_content, meta_value FROM wp_posts, wp_postmeta WHERE ID = post_id and meta_key = '_wp_attached_file'
But this will only show if there is a meta_key equal to '_wp_attached_file'.
The query should show all posts and if it has a meta_key equal to '_wp_attached_file'. Then show meta_value else just show nothing or NULL?
How can i do this?
Use LEFT JOIN
SELECT post_title, post_content, meta_value
FROM wp_posts
LEFT JOIN
wp_postmeta ON ID = post_id
and meta_key = '_wp_attached_file'

MySQL query with multiple where clauses

I have a table wp_postmeta with columns called meta_key and meta_value. I have 5 records in meta_key (location,area,price,bedrooms,bathrooms)
For example, I want to find a hotel in Texas with 2 bathrooms:
select post_id from wp_postmeta where meta_key = 'location' and meta_value = 'texas' and where meta_key = 'bathrooms' and meta_value= '2';
I know the above SQL command is not valid. Can anyone please help me to achieve the above result?
You can try mysql subquery:
select post_id
from wp_postmeta
where meta_key = 'location' and meta_value = 'texas'
and post_id IN (select post_id
from wp_postmeta
where meta_key = 'bathrooms' and meta_value= '2')