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)
Related
This question already has answers here:
Referencing a query result alias in a subquery
(3 answers)
Closed 2 years ago.
Joins can be formulated in an explicit syntax ([INNER|LEFT|OUTER|..] JOIN... ON...) or specifying the conditions in the WHERE statement.
How can I refer to a table called in the external FROM statement and JOIN it in the subquery?
In this case I'm referring to the table with the alias p
SELECT
p.id,
p.post_title,
(SELECT
GROUP_CONCAT(DISTINCT wp_terms.name
SEPARATOR ',')
FROM
p
JOIN
wp_term_relationships ON (p.id = wp_term_relationships.object_id)
LEFT JOIN
wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
LEFT JOIN
wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
AND wp_term_taxonomy.taxonomy IN ('post_tag' , 'category'))
FROM
`post_senza_revisioni` p
WHERE
p.post_type = 'post'
AND p.post_status = 'publish'
AND p.post_parent = 0
GROUP BY id , post_title
I'm pretty sure you want a correlated subquery:
SELECT p.id, p.post_title,
(SELECT GROUP_CONCAT(DISTINCT wp_terms.nameSEPARATOR ',')
FROM wp_term_relationships tr
wp_term_taxonomy tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id LEFT JOIN
wp_terms t
ON t.term_id = tt.term_id AND
tt.taxonomy IN ('post_tag' , 'category'))
WHERE p.id = r.object_id
)
FROM `post_senza_revisioni` p
WHERE p.post_type = 'post' AND
p.post_status = 'publish' AND
p.post_parent = 0;
I doubt the GROUP BY is needed in the outer query, so I removed it. If you do have duplicate id values in the p table, then you can add it back in -- although that suggests that id is a really bad name for the column.
Without knowing the data you, I think you should be able to use the sub query in the FROM clause, join on the ID and then just select * or your desired columns from the sub query.
SELECT
p.id,
p.post_title,
sub.*
FROM
`post_senza_revisioni` p
JOIN (SELECT
GROUP_CONCAT(DISTINCT wp_terms.name
SEPARATOR ',')
FROM
p
JOIN
wp_term_relationships ON (p.id = wp_term_relationships.object_id)
LEFT JOIN
wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id)
LEFT JOIN
wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
AND wp_term_taxonomy.taxonomy IN ('post_tag' , 'category')
) sub
ON p.id = sub.id
WHERE
p.post_type = 'post'
AND p.post_status = 'publish'
AND p.post_parent = 0
GROUP BY id , post_title
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
I'm using the following SQL query to get the records I need from a Wordpress database.
SELECT p.id, p.post_title, m.meta_key, m.meta_value, t.slug
FROM wp_posts p
INNER JOIN wp_postmeta m ON p.id=m.post_id
AND m.meta_key='_subscription_sign_up_fee'
INNER JOIN wp_term_relationships AS tr ON p.id = tr.object_id
INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN wp_terms AS t ON tt.term_id = t.term_id
WHERE t.slug = 'bundle'
This pulls the correct records. My issue is that I need to increase the value of the _subscription_sign_up_fee by 100.
I've tried the following
update wp_postmeta
set wp_postmeta.meta_value = wp_postmeta.meta_value + 100
INNER JOIN wp_postmeta m ON wp_posts.id=m.post_id
AND m.meta_key='_subscription_sign_up_fee'
INNER JOIN wp_term_relationships AS tr ON wp_posts.id = tr.object_id
INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN wp_terms AS t ON tt.term_id = t.term_id
WHERE t.slug = 'bundle'
and get an error saying that 'Column 'meta_value' in field list is ambiguous '
I'm pretty sure I'm not understanding the aliases. Can someone point me in the right direction?
The correct syntax for MySQL UPDATE JOINs is to have SET at the end. You also have some problems in that you're joining wp_postmeta twice, but lost the join with wp_posts.
Something like this should work;
UPDATE wp_postmeta m
JOIN wp_posts
ON wp_posts.id = m.post_id AND m.meta_key = '_subscription_sign_up_fee'
JOIN wp_term_relationships AS tr
ON wp_posts.id = tr.object_id
JOIN wp_term_taxonomy AS tt
ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS t
ON tt.term_id = t.term_id
SET m.meta_value = m.meta_value + 100
WHERE t.slug = 'bundle'
...and always remember to back up your data before running potentially destructive operations from random people on the Internet :)
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?
I need some help with a query that should return posts based on their wp-postratings score (http://wordpress.org/extend/plugins/wp-postratings/).
The user chooses a minimum rating (0 to 5 stars) and a maximum rating (0 to 5 stars) and the query should return the posts that match. I have it working where the user input for both values is above 0 but I can't seem to get my head around the 0 value. Since 0 represents unrated posts - and hence onces that have no ratings meta data - I need to select not only the posts where the rating is no more than the specified max value, but also every post that has no rating meta data.
How can I do this?? Any help will be very much appreciated!
Here's my current query:
SELECT DISTINCT p.*, (t1.meta_value+0.00) AS ratings_average, (t2.meta_value+0.00) AS ratings_users, (t3.meta_value+0.00) AS ratings_score
FROM wp_posts p
INNER JOIN wp_term_relationships tr ON (p.ID = tr.object_id)
INNER JOIN wp_term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
INNER JOIN wp_terms t ON t.term_id = tt.term_id
LEFT JOIN wp_postmeta AS t1 ON t1.post_id = p.ID
LEFT JOIN wp_postmeta AS t2 ON t1.post_id = t2.post_id
LEFT JOIN wp_postmeta AS t3 ON t3.post_id = p.ID
WHERE t1.meta_key = 'ratings_average'
AND t2.meta_key = 'ratings_users'
AND t3.meta_key = 'ratings_score'
AND p.post_date < NOW()
AND p.post_status = 'publish'
AND (tt.taxonomy = 'post_tag' AND tt.term_id = t.term_id AND t.slug = 'liverpool')
AND ( (t1.meta_value+0.00) IS NULL OR (t1.meta_value+0.00) <= $max_stars )
ORDER BY p.post_date DESC
LIMIT 20
I had to do something similar a while back where I was running a cron job to send posts to another application that weren't already registered. The best method I found was to write a query that checked that the ID was NOT IN a query of posts with the meta key.
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
AND $wpdb->posts.ID NOT IN (
SELECT $wpdb->posts.ID
FROM $wpdb->posts
left join $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE $wpdb->posts.post_status = 'publish'
AND $wpdb->postmeta.meta_key = 'meta_key')
I believe this should work, though I obviously haven't tested it.
SELECT DISTINCT p.*, (t1.meta_value+0.00) AS ratings_average, (t2.meta_value+0.00) AS ratings_users, (t3.meta_value+0.00) AS ratings_score
FROM wp_posts p
INNER JOIN wp_term_relationships tr ON (p.ID = tr.object_id)
INNER JOIN wp_term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
INNER JOIN wp_terms t ON t.term_id = tt.term_id
LEFT JOIN wp_postmeta AS t1 ON t1.post_id = p.ID
LEFT JOIN wp_postmeta AS t2 ON t1.post_id = t2.post_id
LEFT JOIN wp_postmeta AS t3 ON t3.post_id = p.ID
WHERE t1.meta_key = 'ratings_average'
AND t2.meta_key = 'ratings_users'
AND t3.meta_key = 'ratings_score'
AND p.post_date < NOW()
AND p.post_status = 'publish'
AND (tt.taxonomy = 'post_tag'
AND tt.term_id = t.term_id
AND t.slug = 'liverpool')
AND (
p.ID NOT IN (
SELECT p.ID
FROM wp_posts AS p
LEFT JOIN wp_postmeta AS pm ON (pm.post_id = p.ID)
WHERE pm.meta_key = 'ratings_score'
)
OR
(t1.meta_value+0.00) <= $max_stars )
ORDER BY p.post_date DESC
LIMIT 20
Okay, this query seems to work for me. Its a bit ugly though and not too quick so if anyone has a better one feel free to improve upon it!
It selects all of the rated posts that are below the $max_stars value, then combines the table with a separate select which gets all of the non-rated posts:
(SELECT DISTINCT p.*, (t1.meta_value+0.00) AS ratings_average, (t2.meta_value+0.00) AS ratings_users, (t3.meta_value+0.00) AS ratings_score
FROM wp_posts p
INNER JOIN wp_term_relationships tr ON (p.ID = tr.object_id)
INNER JOIN wp_term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
INNER JOIN wp_terms t ON t.term_id = tt.term_id
LEFT JOIN wp_postmeta AS t1 ON t1.post_id = p.ID
LEFT JOIN wp_postmeta AS t2 ON t2.post_id = p.ID
LEFT JOIN wp_postmeta AS t3 ON t3.post_id = p.ID
WHERE t1.meta_key = 'ratings_average'
AND t2.meta_key = 'ratings_users'
AND t3.meta_key = 'ratings_score'
AND p.post_date < NOW()
AND p.post_status = 'publish'
AND (tt.taxonomy = 'post_tag' AND tt.term_id = t.term_id AND t.slug = 'liverpool')
AND (t1.meta_value+0.00) <= $max_stars )
UNION
(SELECT DISTINCT p.*, NULL AS ratings_average, NULL AS ratings_users, NULL AS ratings_score
FROM wp_posts p
INNER JOIN wp_term_relationships tr ON (p.ID = tr.object_id)
INNER JOIN wp_term_taxonomy tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
INNER JOIN wp_terms t ON t.term_id = tt.term_id
LEFT JOIN wp_postmeta AS t1 ON (t1.post_id = p.ID AND t1.meta_key = 'ratings_score')
WHERE t1.post_id is null
AND p.post_date < NOW()
AND p.post_status = 'publish'
AND (tt.taxonomy = 'post_tag' AND tt.term_id = t.term_id AND t.slug = 'liverpool') )
ORDER BY post_date DESC