Select only one term_id from taxonomy - mysql

I have a custom post type and a taxonomy, where I can put more the one value to the taxonomy, in this case the taxonomy is the city. I want to make a query that the result is the posts that only have ONE value set. Example: I want all posts that the taxnomy is only "term_id = 3" that is "sao-paulo-sp".
But I have some posts that has more than one value set to it, like "sao-paulo-sp, city 2, city 3 city 4, etc" and this kinda of post keep showing up in my results.
SELECT wp.ID, wp.post_title, wt.term_id FROM wp_posts wp
INNER JOIN wp_term_relationships wtr ON (wp.`ID` = wtr.`object_id`)
INNER JOIN wp_term_taxonomy wtt ON (wtr.`term_taxonomy_id` =
wtt.`term_taxonomy_id`)
INNER JOIN wp_terms wt ON (wt.`term_id` = wtt.`term_id`)
WHERE wtt.taxonomy = 'cities'
AND wt.slug = 'sao-paulo-sp'
ORDER BY wp.ID
I would like that the result was the posts that only have "sao-paulo-sp" or "term_id = 3' as his value to the taxonomy cities

If I understand correctly, you want something like this:
SELECT wp.ID, wp.post_title, wt.term_id
FROM wp_posts wp INNER JOIN
wp_term_relationships wtr
ON wp.`ID` = wtr.`object_id` INNER JOIN
wp_term_taxonomy wtt
ON wtr.`term_taxonomy_id` = wtt.`term_taxonomy_id` INNER JOIN
wp_terms wt
ON wt.`term_id` = wtt.`term_id`
WHERE wtt.taxonomy = 'cities'
GROUP BY wp.ID
HAVING COUNT(*) = 1 AND MAX(wt.slug) = 'sao-paulo-sp'
ORDER BY wp.ID;
I am not sure what wt.term_id is doing in the SELECT list.

Srry, my english was not good enough to specify my question, if help anyone I solved my problem doing a NOT IN in a select that has term_id different than tem_id 3.
SELECT wp.ID, wp.post_title, wt.slug
FROM wp_posts wp
INNER JOIN wp_term_relationships wtr ON wp.`ID` = wtr.`object_id`
INNER JOIN wp_term_taxonomy wtt ON wtr.`term_taxonomy_id` =
wtt.`term_taxonomy_id`
INNER JOIN wp_terms wt ON wt.`term_id` = wtt.`term_id`
WHERE wtt.taxonomy = 'cidades'
AND wp.ID NOT IN
(SELECT wp.ID
FROM wp_posts wp
INNER JOIN wp_term_relationships wtr ON wp.`ID` = wtr.`object_id`
INNER JOIN wp_term_taxonomy wtt ON wtr.`term_taxonomy_id` =
wtt.`term_taxonomy_id`
WHERE wtt.taxonomy ='cidades' and wtt.term_id <> 3)
ORDER BY wp.ID

Related

Woocommerce Mysql query to fetch products and varables

Trying to fetch products ID and the products variable ID in Mysql.
My category is 7006.
This query gives me only the general product, and not the product variables values.
SELECT post.ID, post.post_title, metavalue1.meta_value AS MetaValue1, metavalue2.meta_value AS MetaValue2
FROM wp_posts post
LEFT JOIN wp_postmeta metavalue1 ON post.ID = metavalue1.post_id
AND '_enable_colorlab' = metavalue1.meta_key
LEFT JOIN wp_postmeta metavalue2 ON post.ID = metavalue2.post_id
AND '_wcpa_product_meta' = metavalue2.meta_key
LEFT JOIN wp_term_relationships rs ON rs.object_id = post.ID
WHERE rs.term_taxonomy_id ='7006';
This query gives me all variables ID i need
SELECT post.ID, post.post_title FROM wp_posts post
INNER JOIN wp_postmeta pa ON pa.post_id = post.ID
INNER JOIN wp_term_relationships rs ON rs.object_id = post.ID
WHERE rs.term_taxonomy_id ='7006';
How can i get first query to include all product and variables values and not the general product value?
IT will return variation products with variant id.
SELECT wp.id AS `Product Id`, wpv.id AS `Variant Id`, wp.post_title, wpv.post_title, wpv.post_excerpt
FROM wp_posts wp
INNER JOIN wp_term_relationships r ON wp.ID = r.object_id
INNER JOIN wp_term_taxonomy tt ON r.term_taxonomy_id = 7006
INNER JOIN wp_terms t ON t.term_id = tt.term_id
INNER JOIN wp_posts wpv ON wp.id = wpv.post_parent
LEFT JOIN wp_postmeta wpm ON wp.ID = wpm.post_id
WHERE tt.taxonomy = 'product_type'
AND t.name = 'variable'
AND wpv.post_type != 'attachment'
AND wpm.meta_key = '_enable_colorlab'
You can try something like this:
select
p.id,
p.post_title,
group_concat(concat(m.meta_key, ':', m.meta_value))
from
wp_posts as p
left join wp_postmeta as m on m.post_id = p.id
left join wp_term_relationships rs on rs.object_id = p.id
where
rs.term_taxonomy_id = '7006'
group by
p.id,
p.post_title
In PHP you can explode concatenated string of values

SQL - Multiple Where in one column

Sorry Guys I was using a different example, instead of using COuntry table from w3school I updated my question and give you the real situation.
Im using wordpress and I want to filter out all posts with multiple categories.
`SELECT DISTINCT p.id,p.post_title,p.post_content,t.name,tax.taxonomy from
wp_posts as p
LEFT JOIN wp_term_relationships rel ON rel.object_id = p.ID
LEFT JOIN wp_term_taxonomy tax ON tax.term_taxonomy_id =
rel.term_taxonomy_id
LEFT JOIN wp_terms t ON t.term_id = tax.term_id
WHERE 1=1
AND p.post_status = 'publish'
AND p.post_title LIKE '%lorem%'
OR p.post_content LIKE '%lorem%' `
I want to use raw sql because I know that conditions will be longer than that.
Here is what Iam getting
https://d.pr/free/i/mrNHXk
But when I added this
`AND t.name = 'CGN'
AND t.name = 'Harmony'`
I got no result, iam expecting this
https://d.pr/free/i/0NER1F
Using
AND t.name IN ('CGN','Harmony')
Will not work because The result must have both 'cgn' and 'harmony', if I added 'cfw' on the condition like
AND t.name IN ('CGN','Harmony','cfw')
The result post should have those 3 categories
Do not join directly with the taxonomy tables, but use a subquery and the exists predicate to check whether the tags Harmony and CGN exist for the post.
select p.id, p.post_title, p.post_content,
(select GROUP_CONCAT(t.name) from wp_term_relationships rel
inner join wp_term_taxonomy tax ON tax.term_taxonomy_id = rel.term_taxonomy_id
inner join wp_terms t ON t.term_id = tax.term_id
where rel.object_id = p.ID) as terms
from wp_posts as p
where
p.post_status = 'publish'
and (p.post_title LIKE '%lorem%' OR p.post_content LIKE '%lorem%' )
and exists (select * from wp_term_relationships rel
inner join wp_term_taxonomy tax ON tax.term_taxonomy_id = rel.term_taxonomy_id
inner join wp_terms t ON t.term_id = tax.term_id
where rel.object_id = p.ID and t.name = 'Harmony')
and exists (select * from wp_term_relationships rel
inner join wp_term_taxonomy tax ON tax.term_taxonomy_id = rel.term_taxonomy_id
inner join wp_terms t ON t.term_id = tax.term_id
where rel.object_id = p.ID and t.name = 'CGN')
you will not get any results of that query. The reason is that the Country value can't be both 'Germany' and 'USA' at the same time (in a logical/propositional way).
Try:
SELECT * FROM Customers WHERE Country in ('Germany','USA')
other possibility:
SELECT * FROM Customers WHERE Country like '%Germany%' or like '%USA%'
As stated above, the case where country is both Germany and USA shouldn't exist. It would seem you are looking for:
SELECT * FROM Customers
WHERE Country IN ('Germany', 'USA');
Using the IN clause with a list will return all rows in the customer table where the country contains either Germany or USA.
https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_in2

Get list of products that don't have a specific taxonomy in WooCommerce

I've hit an issue trying to find out what products are missing suppliers on a website with tens of thousands of products.
I need an MySQL query to determine which products are missing the taxonomy "suppliers" through phpmyadmin.
So far I've pieced this together from various answers:
SELECT *
FROM wp_posts wp
INNER JOIN wp_postmeta wm ON (wm.`post_id` = wp.`ID`)
INNER JOIN wp_term_relationships wtr ON (wp.`ID` = wtr.`object_id`)
INNER JOIN wp_term_taxonomy wtt ON (wtr.`term_taxonomy_id` = wtt.`term_taxonomy_id`)
INNER JOIN wp_terms wt ON (wt.`term_id` = wtt.`term_id`)
AND wtt.`taxonomy` = 'suppliers'
WHERE post_type = 'product'
GROUP BY wp.ID
I've tried numerous things and cannot get it to work.
The problem is with you query is that you are not excluding product that has suppliers that that product has some other attributes, so you can use NOT EXIST or NOT IN, I have written the query using NOT EXIST.
SELECT *
FROM wp_posts wp
INNER JOIN wp_postmeta wm ON wm.`post_id` = wp.`ID`
INNER JOIN wp_term_relationships wtr ON (wp.`ID` = wtr.`object_id`)
INNER JOIN wp_term_taxonomy wtt ON wtr.`term_taxonomy_id` = wtt.`term_taxonomy_id`
INNER JOIN wp_terms wt ON wt.`term_id` = wtt.`term_id`
WHERE post_type = 'product'
AND NOT EXISTS
(SELECT `object_id`
FROM `wp_term_relationships` AS wtr_inner
WHERE `term_taxonomy_id` IN
(SELECT term_taxonomy_id
FROM `wp_term_taxonomy`
WHERE `taxonomy` = 'suppliers')
AND wtr.object_id = wtr_inner.object_id )
GROUP BY wp.ID
Another version which will be a bit faster if you know all the suppliers term_taxonomy_id So you can modify the above query as
SELECT *
FROM wp_posts wp
INNER JOIN wp_postmeta wm ON wm.`post_id` = wp.`ID`
INNER JOIN wp_term_relationships wtr ON (wp.`ID` = wtr.`object_id`)
INNER JOIN wp_term_taxonomy wtt ON wtr.`term_taxonomy_id` = wtt.`term_taxonomy_id`
INNER JOIN wp_terms wt ON wt.`term_id` = wtt.`term_id`
WHERE post_type = 'product'
AND NOT EXISTS
(SELECT `object_id`
FROM `wp_term_relationships` AS wtr_inner
WHERE `term_taxonomy_id` IN (27,28,29) -- replace it will all suppliers term_taxonomy_id
AND wtr.object_id = wtr_inner.object_id )
GROUP BY wp.ID
Hope this helps!

Get Wordpress posts that match 2 different categories via custom SQL statement

I'm looking to write a custom SQL statement that will pull published posts from a Wordpress DB that match 2 different categories.
Category 1 (Static) = "Website-1"
Category 2 (Dynamic) = "News", "Tips", "Recreation", etc.
This is a little out of my realm so any help would be greatly appreciated.This is what I have so far:
select p.* from wp_terms wt
join wp_term_taxonomy t on wt.term_id = t.term_id
join wp_term_relationships wpr on wpr.term_taxonomy_id = t.term_taxonomy_id
join wp_posts p on p.id = wpr.object_id
where
t.taxonomy = 'category' and
wt.name = 'Website-1' and
p.post_status = 'publish'
group by p.id
order by p.post_date desc
limit 10
It will pull the first category no problem but I need it to match on 2 categories.
Any insight would be greatly appreciated.
Thanks!
The solution I came up with:
select p.* from wp_posts p
join wp_term_relationships tr on p.id = tr.object_id
join wp_term_taxonomy tt on tt.term_taxonomy_id = tr.term_taxonomy_id
join wp_terms t on t.term_id = tt.term_id
where p.id in
(select tr2.object_id from wp_term_relationships tr2
join wp_term_taxonomy tt2 on tt2.term_taxonomy_id = tr2.term_taxonomy_id
join wp_terms t2 on t2.term_id = tt2.term_id
where
tt2.taxonomy = 'category' and
t2.name in ('Website-1') and
p.id = tr2.object_id
) and
p.post_status = 'publish' and
tt.taxonomy = 'category' and
t.name in ('News')
group by p.id
order by p.post_date desc
limit 10
I'm sure there's a better way to write this query since it's pretty messy but it works for now.
Try having instead of where after group by. I would add this as question / comment but I don't have enough points... what happens if you switch the order of the categories?

Select Post with the term id

I am having a situation where i need to select a post but with where condition as shown :-
Post with both the selected terms at once.
I have tried :-
SELECT p.ID, p.post_title FROM wp_posts p
LEFT JOIN `wp_term_relationships` t
ON p.ID = t.object_id
LEFT JOIN `wp_term_taxonomy` tt
ON t.term_taxonomy_id = tt.term_taxonomy_id
WHERE tt.term_id =86
AND tt.term_id=39
GROUP BY t.object_id
HAVING COUNT( t.term_taxonomy_id ) =2
LIMIT 0,7
Here i want to select a post which is having the term id 86 & 39. These both ids are in same table.
What is the relationship between these tables?
This select works, but I think you can try another way, do you have the TAG instead of the code? Anyway, check this out.
SELECT
p.ID
FROM
wp_posts p
LEFT JOIN wp_term_relationships t ON (p.ID = t.object_id)
WHERE
exists (
SELECT tt.term_taxonomy_id FROM wp_term_taxonomy tt
WHERE tt.term_taxonomy_id = t.term_taxonomy_id
and tt.term_id in(86,39)
)
group by p.ID
having count(p.ID) = 2
Use the IN clause
SELECT p.ID
,p.post_title
FROM wp_posts p
LEFT JOIN 'wp_term_relationships' t ON p.ID = t.object_id
LEFT JOIN 'wp_term_taxonomy' tt ON t.term_taxonomy_id = tt.term_taxonomy_id
WHERE tt.term_id IN (86,39)
GROUP BY t.object_id
HAVING COUNT(t.term_taxonomy_id) = 2 LIMIT 0,7
You can write your where condition as follow:
WHERE tt.term_id in (86,39)