How to Change my Select SQL to Update SQL? - mysql

I have managed to write the following SQL that gives me all records that have the same value in _price, _regular_price & _sale_price.
I need to update _sale_price on these records only to ' ' (nothing / empty)
Here is my working Select:
SELECT p.id, p.post_title, p1.meta_key, p1.meta_value, p2.meta_key, p2.meta_value, p3.meta_key, p3.meta_value
FROM sm_posts p
INNER JOIN sm_postmeta p1 ON p.id = p1.post_id
AND p1.meta_key = '_price'
INNER JOIN sm_postmeta p2 ON p.id = p2.post_id
AND p2.meta_key = '_regular_price'
INNER JOIN sm_postmeta p3 ON p.id = p3.post_id
AND p3.meta_key = '_sale_price'
WHERE p1.meta_value = p2.meta_value AND p1.meta_value = p3.meta_value
I need to create an Update from this but cant figure it out.
So far I have this but its not working:
UPDATE sm_postmeta2,
(
SELECT p.id, p.post_title, p1.meta_key, p1.meta_value, p2.meta_key, p2.meta_value, p3.meta_key, p3.meta_value
FROM sm_posts p
INNER JOIN sm_postmeta2 p1 ON p.id = p1.post_id
AND p1.meta_key = '_price'
INNER JOIN sm_postmeta2 p2 ON p.id = p2.post_id
AND p2.meta_key = '_regular_price'
INNER JOIN sm_postmeta2 p3 ON p.id = p3.post_id
AND p3.meta_key = '_sale_price'
WHERE p1.meta_value = p2.meta_value AND p1.meta_value = p3.meta_value
GROUP BY p1.ID
)
SET sm_postmeta2.meta_value = ''
WHERE sm_postmeta2.meta_value.id = p1.id
Please can someone help, i am new to SQL and it took me forever just to get the joins working. lol
Thank you for taking the time to help me.

Your error means that you must alias the subquery. However, you don't want to put the subquery in the UPDATE clause. If you do, MySQL either won't allow it, or it will update the temporary table resulting from the subquery, i.e. the changes wouldn't persist. Instead, you can INNER JOIN on the subquery to get the rows you want to update.
Since you're just using the subquery to determine the rows to update, you don't need to SELECT all the same values as before. Instead, you can just SELECT the primary key for the records you want to update.
Here's an example:
UPDATE sm_postmeta2 INNER JOIN
(
SELECT DISTINCT p3.meta_id
FROM sm_posts p
INNER JOIN sm_postmeta2 p1 ON p.id = p1.post_id
AND p1.meta_key = '_price'
INNER JOIN sm_postmeta2 p2 ON p.id = p2.post_id
AND p2.meta_key = '_regular_price'
INNER JOIN sm_postmeta2 p3 ON p.id = p3.post_id
AND p3.meta_key = '_sale_price'
WHERE p1.meta_value = p2.meta_value AND p1.meta_value = p3.meta_value
) p_tmp ON sm_postmeta2.meta_id = p_tmp.meta_id
SET sm_postmeta2.meta_value = ''

Related

Getting number of purchased items using SQL - Woocommerce

I'm stuck in this query for while and any type of help would be appreciated. This is for a wordpress website which uses woocommerce.
Trying to get purchase details of customers and I need to get a result set which should contain following fields.
Email | First Name | Orders | Items Purchased | Order Total
I've written the following SQL for this purpose. achg8 is the table prefix. An order may have one or more items.
SELECT
pm1.meta_value as email ,
pm2.meta_value as first_name,
sum(pm3.meta_value) as total,
count(posts.ID) as orders ,
count(items.order_item_id) as items
from achg8_posts as posts
left join achg8_postmeta as pm1 on posts.ID = pm1.post_id
left join achg8_postmeta as pm2 on posts.ID = pm2.post_id
left join achg8_postmeta as pm3 on posts.ID = pm3.post_id
left join achg8_woocommerce_order_items as items on items.order_id = posts.ID
WHERE
posts.post_type = 'shop_order' and
posts.post_status = 'wc-processing' and
pm1.meta_key='_billing_email' and
pm2.meta_key='_billing_first_name' and
pm3.meta_key='_order_total'
GROUP by email
The problem is order number and item numbers are always equal. but that's not the case actually.
Need and insight on what i'am doing wrong.
UPDATE
edited the sql to the following as per #matigo's comment. The problem now is the order total gets added up multiple times. For an example if an order has two items (i.e two rows in the joined resultset) order-total gets added up twice.
SELECT
pm1.meta_value as email ,
pm2.meta_value as first_name,
sum(pm3.meta_value) as total,
count(DISTINCT posts.ID) as orders ,
count(items.order_item_id) as items
from achg8_posts as posts
left join achg8_postmeta as pm1 on posts.ID = pm1.post_id
left join achg8_postmeta as pm2 on posts.ID = pm2.post_id
left join achg8_postmeta as pm3 on posts.ID = pm3.post_id
left join achg8_woocommerce_order_items as items on items.order_id = posts.ID
WHERE
posts.post_type = 'shop_order' and
posts.post_status = 'wc-processing' and
pm1.meta_key='_billing_email' and
pm2.meta_key='_billing_first_name' and
pm3.meta_key='_order_total'
GROUP by email
Assuming that the same order number can appear in items multiple times, it looks like you need a DISTINCT in your COUNT.
Try this:
SELECT pm1.`meta_value` as `email`,
pm2.`meta_value` as `first_name`,
SUM(pm3.`meta_value`) as `total`,
COUNT(posts.`ID`) as `orders`,
(SELECT COUNT(z.`order_item_id`)
FROM `achg8_woocommerce_order_items` z
WHERE posts.`ID` = z.`order_id`) as `items`
FROM `achg8_posts` posts INNER JOIN `achg8_postmeta` pm1 ON posts.`ID` = pm1.`post_id`
INNER JOIN `achg8_postmeta` pm2 ON posts.`ID` = pm2.`post_id`
INNER JOIN `achg8_postmeta` pm3 ON posts.`ID` = pm3.`post_id`
WHERE posts.`post_type` = 'shop_order'
and posts.`post_status` = 'wc-processing'
and pm1.`meta_key` = '_billing_email'
and pm2.`meta_key` = '_billing_first_name'
and pm3.`meta_key` = '_order_total'
GROUP by `email`, `first_name`
This should give you exactly what you're looking for 👍🏻
Can you try this and see if it works.
Sorry, I removed that joins without considering the relation with meta_key, can you try this.
SELECT
pm1.`meta_value` as `email`,
pm2.`meta_value` as `first_name`,
SUM(pm3.`meta_value`) as `total`,
COUNT(distinct posts.`ID`) as `orders`,
COUNT(distinct items.order_item_id) as `items`
FROM `achg8_posts` posts
INNER JOIN `achg8_postmeta` pm1 ON posts.`ID` = pm1.`post_id`
INNER JOIN `achg8_postmeta` pm2 ON posts.`ID` = pm2.`post_id`
INNER JOIN `achg8_postmeta` pm3 ON posts.`ID` = pm3.`post_id`
INNER JOIN achg8_woocommerce_order_items as items on items.order_id = posts.ID
WHERE
posts.`post_type` = 'shop_order' and
posts.`post_status` = 'wc-processing' and
pm1.`meta_key` = '_billing_email' and
pm2.`meta_key` = '_billing_first_name' and
pm3.`meta_key` = '_order_total'
GROUP by `email`

COUNT() not displaying correct result

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).

MySQL UPDATE with LEFT JOINS

This is my query:
UPDATE
`product_pricing`
SET `formula_id`= '2'
WHERE 1
SELECT
product_pricing.id,
product_pricing.formula_id,
product_pricing.vat_calculated,
products_ids.id,
products_ids.link_id,
product_attributes.fty_id,
product_attributes.size_id,
product_sizes.size_id,
product_sizes.wheel
FROM product_pricing
LEFT JOIN products_ids ON product_pricing.id = products_ids.id
LEFT JOIN product_attributes ON products_ids.link_id = product_attributes.fty_id
LEFT JOIN product_sizes ON product_attributes.size_id = product_sizes.size_id
WHERE
product_sizes.wheel = '13'
How would I incorporate the SELECT query with the update query?
I need to only update products that have product_sizes.wheel = '13' but to get this information, I need a few left joins.
You can use this update with LEFT JOIN and Where
update product_pricing
LEFT JOIN products_ids ON product_pricing.id = products_ids.id
LEFT JOIN product_attributes ON products_ids.link_id = product_attributes.fty_id
LEFT JOIN product_sizes ON product_attributes.size_id = product_sizes.size_id
SET product_pricing.formula_id= '2'
WHERE
product_sizes.wheel = '13'
I think an INNER JOIN is needed here:
update product_pricing
INNER JOIN products_ids ON product_pricing.id = products_ids.id
INNER JOIN product_attributes ON products_ids.link_id = product_attributes.fty_id
INNER JOIN product_sizes ON product_attributes.size_id = product_sizes.size_id
SET product_pricing.formula_id= '2'
WHERE product_sizes.wheel = '13'
try this
update product_pricing p
LEFT JOIN products_ids pi ON p.id = pi.id
LEFT JOIN product_attributes pa ON pi.link_id = pa.fty_id
LEFT JOIN product_sizes ps ON pa.size_id = ps.size_id
SET p.formula_id= '2'
WHERE
ps.wheel = '13'

My SQL query pulls inaccurate information about variable woocommerce products, but works fine for regular products. Why?

I have a rather long and complicated sql query that I use to pull product reports from Woocommerce (because the browser reports do not contain enough information for my superiors' liking) For the most part, it works wonderfully. But it gives me incorrect/unreliable data for variable products, and I am not sure why this is.
Query follows:
SELECT p.ID, b.meta_value, p.post_title, pv.meta_value, SUM( qty.meta_value ), var.meta_value, "CR [4/3]", SUM( tot.meta_value ), "Avg Prc [6/4] 3?", pr.meta_value, AVG(aic.meta_value) , "Grs Prft [(8-9)/8]", "GrAvPrft [(7-9)/7]", "Grs Markup [(8-9)/8]"
FROM wp_posts p INNER JOIN wp_woocommerce_order_itemmeta pid ON p.ID = pid.meta_value AND pid.meta_key = '_product_id'
INNER JOIN wp_woocommerce_order_itemmeta qty ON pid.order_item_id = qty.order_item_id AND qty.meta_key = '_qty'
INNER JOIN wp_woocommerce_order_itemmeta tot ON tot.order_item_id = qty.order_item_id AND tot.meta_key = '_line_total'
LEFT JOIN wp_woocommerce_order_itemmeta var ON var.order_item_id = qty.order_item_id AND var.meta_key = '_variation_id'
LEFT JOIN wp_woocommerce_order_itemmeta shp ON shp.order_item_id = qty.order_item_id AND shp.meta_key = '_per_product_shipping_cost'
LEFT JOIN wp_postmeta pr ON pr.post_id = p.ID AND pr.meta_key = '_price'
LEFT JOIN wp_postmeta b ON b.post_id = p.ID and b.meta_key = '_bucket'
LEFT JOIN wp_postmeta pv ON p.ID = pv.post_id and pv.meta_key = '_page_views'
LEFT JOIN wp_woocommerce_order_itemmeta aic ON aic.order_item_id = pid.order_item_id and aic.meta_key='_actual_item_cost'
INNER JOIN wp_woocommerce_order_items oim ON oim.order_item_id = pid.order_item_id
INNER JOIN wp_posts ord ON oim.order_id = ord.ID
WHERE p.post_type = 'product'
AND oim.order_item_type = 'line_item'
AND tot.meta_value > 0
AND ord.post_status IN ('wc-completed', 'wc-processing')
GROUP BY p.ID;
Some of the stuff in the select statement is just placeholders for post-query calculations, just ignore those. My main issue is that SUM( qty.meta_value ) and SUM( tot.meta_value ) give incorrect data for variable products.

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