COUNT() not displaying correct result - mysql

I'm having trouble with my code.
SELECT * FROM wp_posts as wposts
LEFT JOIN wp_term_relationships as rs ON (rs.object_id = wposts.ID)
LEFT JOIN wp_postmeta m1 ON (wposts.ID = m1.post_id )
WHERE (wposts.post_type = 'product' AND wposts.post_status = 'publish')
AND ( m1.meta_key = '_stock_status' AND m1.meta_value = 'instock' )
Now the problem is, some of the items are duplicated that's why it displays wrong count.
https://www.screencast.com/t/cmOku8G3nAF
What am I doing wrong?

If you want just a count of posts, remove the group by and select count(distinct wposts.ID).

Related

How to delete entries from a SELECT query result in mysql?

I have the following SQL query :
SELECT wp_posts.* , wicl_translations.*
FROM wp_posts wp_posts join wp_icl_translations wicl_translations
ON (wicl_translations.element_id = wp_posts.ID)
WHERE (wicl_translations.language_code = 'es-es'
AND wicl_translations.element_type ='post_product'
AND wp_posts.post_type = 'product' ) GROUP BY wp_posts.ID
This returns all the results I need to delete from my database so I have tried several DELETE queries but getting syntax errors in all of them .
Example :
DELETE FROM wp_posts
WHERE (
SELECT wp_posts.* , wicl_translations.*
FROM wp_posts wp_posts join wp_icl_translations wicl_translations
ON (wicl_translations.element_id = wp_posts.ID)
WHERE (wicl_translations.language_code = 'pt-pt'
AND wicl_translations.element_type ='post_product'
AND wp_posts.post_type = 'product' ) GROUP BY wp_posts.ID
)
);
Also tried this :
DELETE FROM wp_posts WHERE wp_posts.ID = ANY IN (
SELECT wp_posts.ID, wicl_translations.*
FROM wp_posts wp_posts join wp_icl_translations wicl_translations
ON (wicl_translations.element_id = wp_posts.ID)
WHERE (wicl_translations.language_code = 'es-es'
AND wicl_translations.element_type ='post_product'
AND wp_posts.post_type = 'product' ) GROUP BY wp_posts.ID
)
It`s a complex aggregated query and I lack the mysql knowledge to properly write a rule for deleting these results .
How could I approach this ?
Thanks
If we have a complex query that returns the id value of rows in wp_posts that we want to delete (assuming that id is the primary key or a unique key of a row in the table)... as an example
SELECT p.id
FROM wp_posts p
JOIN wp_icl_translations t
ON t.element_id = p.id
WHERE t.language_code = 'es-es'
AND t.element_type = 'post_product'
AND p.post_type = 'product'
GROUP
BY p.id
We can then use that query as an inline view. We wrap the query in parens and reference it in the FROM clause of another query. MySQL requires that we assign an alias to thhe inline view (or derived table in the MySQL vernacular).
We can join the result from the inline view that back to the table we want to remove rows from. We write this a SELECT statement first
SELECT r.*
FROM ( -- inline view
SELECT p.id
FROM wp_posts p
JOIN wp_icl_translations t
ON t.element_id = p.id
WHERE t.language_code = 'es-es'
AND t.element_type = 'post_product'
AND p.post_type = 'product'
GROUP
BY p.id
) q
JOIN wp_posts r
ON r.id = q.id
to return the set of rows to be removed. We can verify that this is the intended set, or insert (create table as) the set of rows into backup...
Once we are confident that the SELECT is returning the rows we want to remove, we can convert it into a DELETE statement by replacing the SELECT keyword with DELETE.
DELETE r.*
FROM ( -- inline view
SELECT p.id
FROM wp_posts p
JOIN wp_icl_translations t
ON t.element_id = p.id
WHERE t.language_code = 'es-es'
AND t.element_type = 'post_product'
AND p.post_type = 'product'
GROUP
BY p.id
) q
JOIN wp_posts r
ON r.id = q.id
You'r on the right track !
You just miss the correct WHERE condition :
DELETE FROM wp_posts WHERE wp_posts.ids IN (...)
Make sure the result has only one column wich you shall refer to when deleting data from the targetted tables. The delete queries will be equal to the number of tables you will require to delete from ie.
DELETE FROM table_1 where common_column in (YOUR_SELECT_QUERY);
DELETE FROM table_2 where common_column in (YOUR_SELECT_QUERY);
DELETE FROM table_3 where common_column in (YOUR_SELECT_QUERY);
DELETE FROM table_nth where common_column in (YOUR_SELECT_QUERY);
Your select query be like,
SELECT GROUP_CONCAT(temp_tbl.ID) FROM (SELECT wp_posts.* , wicl_translations.*
FROM wp_posts wp_posts join wp_icl_translations wicl_translations
ON (wicl_translations.element_id = wp_posts.ID)
WHERE (wicl_translations.language_code = 'es-es'
AND wicl_translations.element_type ='post_product'
AND wp_posts.post_type = 'product' ) GROUP BY wp_posts.ID) AS temp_tbl

Filter rows without a specific value

I'm querying a wordpress mysql db outside the php language and I don't know how to solve the following problem: each post has taxonomies with some value. There's a value called 'calificaciones' which I'd like to filter on. This is my current query:
SELECT wp_posts.post_title, IF (wp_term_taxonomy.taxonomy = 'calificaciones', wp_terms.slug, 'no') as calificacion
FROM wp_posts
JOIN wp_term_relationships ON (wp_term_relationships.object_id = wp_posts.ID)
JOIN wp_term_taxonomy ON (wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id)
JOIN wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
AND wp_posts.post_type = 'ultimas-noticias'
#AND wp_term_taxonomy.taxonomy = 'calificaciones'
The problem with this query is that I'll get the post_title multiple times(because there are others taxonomies for each post). I'd like to get the post title and a flag yes-no, if the post has that taxonomy value or not.
Instead of joining the taxonomies on the same query you could use a sub query for the calificacion column.
SELECT wp_posts.post_title, CASE WHEN EXISTS((SELECT *
FROM wp_term_relationships
JOIN wp_term_taxonomy ON (wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id)
JOIN wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
WHERE (wp_term_relationships.object_id = wp_posts.ID)
AND wp_term_taxonomy.taxonomy = 'calificaciones'
)) THEN 'YES' ELSE 'NO' END as calificacion
FROM wp_posts
WHERE wp_posts.post_type = 'ultimas-noticias'
You can use select distinct
SELECT distinct wp_posts.post_title, IF (wp_term_taxonomy.taxonomy = 'calificaciones', wp_terms.slug, 'no') as calificacion
FROM wp_posts
JOIN wp_term_relationships ON (wp_term_relationships.object_id = wp_posts.ID)
JOIN wp_term_taxonomy ON (wp_term_taxonomy.term_taxonomy_id = wp_term_relationships.term_taxonomy_id)
JOIN wp_terms ON (wp_terms.term_id = wp_term_taxonomy.term_id)
AND wp_posts.post_type = 'ultimas-noticias'
#AND wp_term_taxonomy.taxonomy = 'calificaciones'

How to filter the GROUP_CONCAT in my SELECT

I am trying to SELECT (all of the multiple) comments from Wordpress which relate to a post (wp_comments.comment_content) with GROUP_CONCAT but I only want to select those comments which DON'T contain the text string "status". If there are no comments at all, or only comments which contain "status" I still want to see those records in the result, just without getting anything back for comments.
When I tried putting a condition similar to [WHERE wp_comments.comment_content NOT LIKE "%status%"] at the end of the complete query, records which only have a comment containing "status" don't display AT ALL, I still need to get those records, just without the comments.
I want to try something like the below version but this throws up an error and doesn't spit out any data at all. (The overall query works as expected btw apart from the comment selection section..).
Maybe I am joining the wp_comments table in the wrong place, using the wrong join, not using a properly formatted nested SELECT or similar, maybe it needs a separate SELECT at the end so I can get the comments back I want in a way which doesn't effect which records are selected overall.. not sure..
Any idea what I am doing wrong or how to approach this?
Here is my query, thanks in advance for any kind pointers!
select wp_woocommerce_order_itemmeta.meta_value as firstwoometavalue,
wp_postmeta.meta_value as firstwpmetavalue, Y.meta_value as ymetavalue,
Z.meta_value as zmetavalue, X.meta_value as xmetavalue,
(GROUP_CONCAT(wp_comments.comment_content) as commentcontent
WHERE wp_comments.comment_type = "order_note" AND
wp_comments.comment_content NOT LIKE "%status%")
FROM wp_postmeta
left JOIN wp_postmeta as Y
ON wp_postmeta.post_id = Y.post_id
left JOIN wp_posts
ON wp_postmeta.post_id = wp_posts.ID
left JOIN wp_woocommerce_order_items
ON wp_woocommerce_order_items.order_id = wp_posts.ID
left JOIN wp_woocommerce_order_itemmeta
ON wp_woocommerce_order_itemmeta.order_item_id = wp_woocommerce_order_items.order_item_id
left JOIN wp_woocommerce_order_itemmeta as Z
ON wp_woocommerce_order_itemmeta.order_item_id = Z.order_item_id
left JOIN wp_woocommerce_order_itemmeta as X
ON wp_woocommerce_order_itemmeta.order_item_id = X.order_item_id
left JOIN wp_comments
ON wp_comments.comment_post_ID = wp_posts.ID
where 1=1
AND wp_woocommerce_order_itemmeta.meta_key ="Adults"
AND wp_postmeta.meta_key ="_billing_first_name"
AND Y.meta_key ="_billing_last_name"
AND Z.meta_key ="Booking Type"
AND Z.meta_value LIKE "%'.$showlocation.'%"
AND X.meta_key ="Booking Date"
AND X.meta_value = "'.$showdate.'"
AND wp_posts.post_status ="wc-completed"
GROUP BY wp_posts.ID
This works
SELECT
wp_woocommerce_order_itemmeta.meta_value AS Adults,
wp_postmeta.meta_value AS FirstName,
jn_postmeta_lastname.meta_value AS LastName,
jn_woocommerce_order_itemmeta_location.meta_value AS Location,
jn_woocommerce_order_itemmeta_date.meta_value AS ShowDate,
(SELECT
GROUP_CONCAT(wp_comments.comment_content)
FROM
wp_comments
WHERE
wp_comments.comment_content NOT LIKE '%status%'
AND wp_comments.comment_post_ID = wp_posts.ID) Notes
FROM
wp_postmeta
LEFT JOIN
wp_postmeta AS jn_postmeta_lastname ON wp_postmeta.post_id = jn_postmeta_lastname.post_id
LEFT JOIN
wp_posts ON wp_postmeta.post_id = wp_posts.ID
LEFT JOIN
wp_woocommerce_order_items ON wp_woocommerce_order_items.order_id = wp_posts.ID
LEFT JOIN
wp_woocommerce_order_itemmeta ON wp_woocommerce_order_itemmeta.order_item_id = wp_woocommerce_order_items.order_item_id
LEFT JOIN
wp_woocommerce_order_itemmeta AS jn_woocommerce_order_itemmeta_location ON wp_woocommerce_order_itemmeta.order_item_id = jn_woocommerce_order_itemmeta_location.order_item_id
LEFT JOIN
wp_woocommerce_order_itemmeta AS jn_woocommerce_order_itemmeta_date ON wp_woocommerce_order_itemmeta.order_item_id = jn_woocommerce_order_itemmeta_date.order_item_id
LEFT JOIN
wp_comments ON wp_comments.comment_post_ID = wp_posts.ID
WHERE
1 = 1
AND (wp_postmeta.meta_key = '_billing_first_name'
AND jn_postmeta_lastname.meta_key = '_billing_last_name'
AND wp_woocommerce_order_itemmeta.meta_key = 'Adults'
AND jn_woocommerce_order_itemmeta_location.meta_key = 'Booking Type'
AND jn_woocommerce_order_itemmeta_location.meta_value LIKE "%'.$showlocation.'%"
AND jn_woocommerce_order_itemmeta_date.meta_key = 'Booking Date'
AND jn_woocommerce_order_itemmeta_date.meta_value = "'.$showdate.'"
AND wp_posts.post_status = 'wc-completed'
GROUP BY wp_posts.ID

mysql sum returning wrong value

Hi there so i have this problem in the following query, inside wp_wti_like_post i have number of rows with similar post_id and with value column as 1 or -1.
So let's say for post with id 727 i have only one row , so the sum should be 1, but don't know why it does return 4 and when there are two rows with 727 it does return 8 query is below:
SELECT wp_posts. * ,
SUM( wp_wti_like_post.value ) -4 AS total_sum,
wp_wti_like_post.post_id
FROM wp_posts
INNER JOIN wp_term_relationships ON ( wp_posts.ID =
wp_term_relationships.object_id )
INNER JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id =
wp_term_taxonomy.term_taxonomy_id )
JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
LEFT JOIN wp_wti_like_post ON ( wp_posts.ID = wp_wti_like_post.post_id )
WHERE wp_term_taxonomy.taxonomy = 'category'
AND wp_term_taxonomy.term_id IN ('$c_cid')
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish')
GROUP BY wp_posts.ID
HAVING SUM( wp_wti_like_post.value ) > $min_like
ORDER BY wp_posts.post_date DESC
You are using joins among many tables and there may b a chance that any of them has many associations for a post_id therefore your sum is incorrect i suggest you to use a sub select for your like table and calculate sum in sub select and then join with your main query
SELECT
p.*, COALESCE(l.sum_like,0) AS total_sum,
l.post_id
FROM
wp_posts p
INNER JOIN wp_term_relationships ttr
ON (p.ID = ttr.object_id)
INNER JOIN wp_term_taxonomy tt
ON (ttr.term_taxonomy_id = tt.term_taxonomy_id)
LEFT JOIN (
SELECT post_id ,SUM(`value`) sum_like
FROM wp_wti_like_post
GROUP BY post_id
) l ON (p.ID = l.post_id)
WHERE tt.taxonomy = 'category'
AND tt.term_id IN ('21')
AND p.post_type = 'post'
AND (p.post_status = 'publish')
HAVING total_sum > 2
ORDER BY p.post_date DESC
Also note i have removed wp_postmeta join because its not used in your selection criteria and neither in your filter criteria also wp_postmeta stores different attributes for each post so i guess this table is producing more rows thats why wrong sum is calculated.
Removed -4 from query

mySql Distinct - group by issue

I'm trying to find out the most purchased products but to only count distinct users ids. Basically my client wants to stop duplicate purchases from the same user, so that they can't affect the chart/best sellers.
I need to count all order_items for that product, using only Distinct users ids. Currently the results are counting all order_items so the Distinct isn't working.
Any help and I would be grateful.
Thanks in advance
SELECT *
FROM
( SELECT DISTINCT
order_item_meta_3.meta_value as distinct_user_order_items_id,
order_item_meta_2.meta_value as product_id,
SUM( order_item_meta.meta_value ) as item_quantity
FROM
wp_woocommerce_order_items as order_items
LEFT JOIN wp_woocommerce_order_itemmeta as order_item_meta
ON order_items.order_item_id = order_item_meta.order_item_id
LEFT JOIN wp_woocommerce_order_itemmeta as order_item_meta_2
ON order_items.order_item_id = order_item_meta_2.order_item_id
LEFT JOIN wp_woocommerce_order_itemmeta as order_item_meta_3
ON order_items.order_item_id = order_item_meta_3.order_item_id
LEFT JOIN wp_posts AS posts
ON order_items.order_id = posts.ID
LEFT JOIN wp_term_relationships AS rel
ON posts.ID = rel.object_ID
LEFT JOIN wp_term_taxonomy AS tax
USING( term_taxonomy_id )
LEFT JOIN wp_terms AS term
USING( term_id )
WHERE
posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug IN ('completed','processing','on-hold')
AND order_items.order_item_type = 'line_item'
AND order_item_meta.meta_key = '_qty'
AND order_item_meta_2.meta_key = '_product_id'
AND order_item_meta_3.meta_key = '_user_id'
GROUP BY
order_item_meta_2.meta_value
ORDER BY
item_quantity DESC ) as order_table,
wp_posts
LEFT JOIN wp_postmeta as mk1
ON wp_posts.ID = mk1.post_id
LEFT JOIN wp_postmeta as mk2
ON wp_posts.ID = mk2.post_id
WHERE
order_table.product_id = wp_posts.ID
AND wp_posts.ID = mk1.post_id
AND mk1.meta_key = 'is_album'
AND mk1.meta_value = 0
AND mk2.meta_key = '_price'
AND mk2.meta_value = 0
Wouldn't you need to do the sum outside the group by. you have to materialize the distinct set first then aggregate it...
so change first few lines to...
SELECT distinct_user_order_items_Id, product_Id, sum(item_Quantity) as item_Quantity
FROM (
SELECT
order_item_meta_3.meta_value as distinct_user_order_items_id,
order_item_meta_2.meta_value as product_id,
order_item_meta.meta_value as item_quantity