Run MySQL SELECT query for each value, returned by another SELECT - mysql

Even though this is basically a WordPress related problem, my question is strictly MySQL, so I am posting here as it probably will be more accurate.
I have two tables, wp_posts that contains basic data (e.g. IDs) of my products, and wp_postmeta that contains all additional data of those posts. I have this query:
SELECT count(p.ID) as in_stock_count
FROM wp_postmeta as pm
INNER JOIN wp_posts as p
ON pm.post_id = p.ID
WHERE p.post_type = 'product_variation'
AND p.post_parent = 123456
AND p.post_status = 'publish'
AND pm.meta_key = '_stock_status'
AND pm.meta_value = 'instock'
I can pass my product ID to this query (note the 123456 ID) and it returns the number of available variations of that product (in_stock_count). The query works very well for a single product ID.
This is a simple query that returns all product IDs from the wp_posts table:
SELECT ID FROM wp_posts WHERE post_type = 'product' AND post_status = 'publish'
I need to somehow merge these two queries, so that the first query would run for each ID returned by the second query. The returned table could have two columns: ID and in_stock_count
I'm kind of stuck here. Thank you for your help.

Related

Build a table one column at a time

I'm trying to build a table in MySQL using multiple fields from different tables, but some of the tables have multiple keyed valued (this is a wordpress database) and there's too many datapoints to run it with a single query. Trying to figure out how to fill in the first three columns, then use those values to fill in the next few columns, etc.
`
INSERT INTO order_output(order_id, order_item_id, customer_id)
SELECT p.ID, wcoi.order_item_id, pm1.meta_value FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items wcoi
ON p.ID = wcoi.order_id
LEFT JOIN wp_postmeta pm1
ON p.ID = pm1.post_id AND pm1.meta_key = '_customer_user'
WHERE p.post_type = 'shop_order' and p.post_status = 'wc-processing';
`
This works fine and fills in the first three columns of the table. But then when I try to run
INSERT INTO order_output(email) SELECT u.user_email FROM wp_users u INNER JOIN order_output oo ON u.ID = oo.customer_id
It won't fill in the email column. I've tried a few variations on this, UNION is throwing an error, it will either do nothing at all or just double the size of the table without ever filling in the email column.

WooCommerce: delete range of orders using a SQL Query

This actually relates to this post which shows how completely delete all the completed orders from a WooCommerce store. I want to do something similar, but instead of deleting all the orders, I just want to delete a range of orders. Let's say anything in the range of Order ID 1,000-2,000.
Here's how you do it from the entire database:
DELETE FROM wp_woocommerce_order_itemmeta
DELETE FROM wp_woocommerce_order_items
DELETE FROM wp_comments WHERE comment_type = 'order_note'
DELETE FROM wp_postmeta WHERE post_id IN ( SELECT ID FROM wp_posts WHERE post_type = 'shop_order' )
DELETE FROM wp_posts WHERE post_type = 'shop_order'
How can I do it from a range?

Get Multiple rows in SQL Query

I'm using a SQL query in JDBC. It is supposed to get:
1- post_id (from table wp_posts) WHERE post_type = product
2- post_title (from table wp_posts) WHERE post_type = product
3- meta_value from table wp_postmeta WHERE (wp_posts.post_id = wp_postmeta.post_id) AND wp_postmeta.meta_key = _stock_status, total_sales, _regular_price, _sale_price, _price, _stock
(from specified META_KEYs from table WP_POSTMETA corresponding to my POST_IDs from table WP_POSTS)
Basically, I'm working on getting WooCommerce product details from WP Database.
This is the code my friend has helped me with so far:
SELECT wp_posts.ID, wp_posts.post_title,wp_postmeta.meta_value FROM wp_posts, wp_postmeta WHERE (wp_posts.ID = wp_postmeta.post_id) AND (wp_postmeta.meta_key='_stock')
Just like it is getting _stock at the end of the query, I want to get 5 more items (_stock_status, total_sales, _regular_price, _sale_price, _price) for each POST_ID
EDIT:
My friend helped me with another query, but it is not getting the information in a single array, instead it makes different array items for each piece of information.
SELECT wp_posts.ID, wp_posts.post_title,wp_postmeta.meta_key,wp_postmeta.meta_value FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id HAVING wp_postmeta.meta_key='_stock' OR wp_postmeta.meta_key='_stock_status' OR wp_postmeta.meta_key='total_sales' OR wp_postmeta.meta_key='_regular_price' OR wp_postmeta.meta_key='_sale_price' OR wp_postmeta.meta_key='_price'
I want the results to come out in a single 2D array.
This select statement below follows the question that wants to include additional meta_key information (not just "_stock"). Change accordingly, as only you have your data.
The OP clearly has typos in this sentence "wp_postmeta.meta_key = _stock_status, total_sales, _reulgar_price, _sale_price, _price, _stock" as well as that query that his "friend" wrote.
SELECT p.ID, p.post_title,m.meta_value
FROM wp_posts p
join wp_postmeta m
on p.ID=m.post_id
AND m.meta_key in ('_stock','_stock_status','total_sales','_regular_price','_sale_price','_price')

Woocommerce SQL query to show products sold this week?

Woocommerce has a reporting tool that will show me the top products sold for the last 7 days. But it only shows the top 12 products.
I am wanting to create a SQL query that will show me all products with their total count sold for the last 7 days instead of just the top 12.
Has anyone done this before?
WooCommerce borrows heavily from the way WordPress itself stores data: a Post serves as the basic data object with a handful of columns common to all custom posts. Any unique data specific to a custom type is stored as key value pairs in post_meta. This means there aren't clean columns or tables to query for things like order line items, sku, line item price, etc.
It's worth mentioning that for orders, WC does not store products it stores line items. This is because you can add fees, generic line items and possibly other things to an order that are not products. Also, WC needs to store the price at the time of the order as the customer may have had a discount or the product price may have changed.
WooCommerce uses both the WordPress postmeta table AND its own order_itemmeta table. Here's how that breaks down:
The order itself is stored as a custom post type of "shop_order" in the wp_posts table
Order line items are stored in a relationship table called wp_woocommerce_order_items
Order item details are stored as key value pairs in wp_woocommerce_order_itemmeta
Finaly order details are stored in the wp_postmeta table
So, let's say you want to see all line items for a period of time and you want to know things like the item title, price and what order it belonged to. To do this you must JOIN multiple tables and either JOIN or subquery the meta tables for the specific fields you want. In the example below I used subqueries because I believe they are more readable, please note that JOINs are very likely faster.
SELECT
-- Choose a few specific columns related to the order
o.ID as order_id,
o.post_date as order_created,
-- These come from table that relates line items to orders
oi.order_item_name as product_name,
oi.order_item_type as item_type,
-- We have to subquery for specific values and alias them. This could also be done as a join
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_product_id") as product_id,
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_product_variation_id") as variant_id,
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_qty") as qty,
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_fee_amount") as fee,
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_line_subtotal") as subtotal,
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_line_subtotal_tax") as tax,
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_line_total") as total,
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_tax_class") as tax_class,
(SELECT meta_value FROM wp_woocommerce_order_itemmeta WHERE order_item_id = oi.order_item_id AND meta_key = "_tax_status") as tax_status,
-- This wasn't specifically mentioned in the question but it might be nice to have some order meta data too
(SELECT meta_value FROM wp_postmeta WHERE post_id = o.ID AND meta_key = "_order_total") as order_total,
(SELECT meta_value FROM wp_postmeta WHERE post_id = o.ID AND meta_key = "_customer_user") as user_id
FROM wp_posts o
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_id = o.id
LEFT JOIN wp_posts p ON p.ID = oi.order_item_id
WHERE o.post_type = "shop_order"
As you can see it takes a subquery/join for every line item field you want making these queries pretty expensive. I suspect that WC limits how much is queried for reports for this reason.
This answer was tested against WC version 3.3.4.
Instead of writin a new query just modify the existing one with filter:
woocommerce_reports_get_order_report_query
Is seems that the limit is the same for all parts of the reports page, so changing this will affect all queries with limit clause. I would not go too far with the number of products because a new sql query is executed for each product listed.
add_filter( 'woocommerce_reports_get_order_report_query', function( $query )
{
if ( isset( $query['limit'] ) ) $query['limit'] = 'LIMIT 20'; <-- set limit to 20 products
return $query;
});
Just a guess
....WHERE dateColumn BETWEEN DATE_SUB(NOW(),INTERVAL 1 WEEK) AND NOW()
Add more info,for a more precise answer.

MySQL | How to get latest articles from each category?

I am using WordPress to build a score system for a company and I have to create a custom Query that not work in my case.
Here (http://sqlfiddle.com/#!2/1f510/1) I have a copy of my real data, as they are in my database, as well the query I am using to extract my data.
As you can see, I get four rows as a result. Each row corresponds to a category, but the issue is that I get the oldest post from each category instead of the latest that is required.
Any idea on how to modify this query in order to get the latest posts from each category ?
SELECT ID AS PostID,
post_title AS PostTitle,
meta_value AS CategoryID,
name AS CategoryName,
post_date AS `Date`
FROM (SELECT *
FROM wp_posts AS p
INNER JOIN wp_postmeta AS m
ON p.ID = m.post_id
INNER JOIN wp_terms AS t
ON m.meta_value = t.term_id
WHERE m.meta_key = 'matchdayTeamsCategory'
ORDER BY p.post_date DESC) tmpView
GROUP BY CategoryName;
Here is one way...
http://sqlfiddle.com/#!2/1f510/34
padding padding padding