Get Multiple rows in SQL Query - mysql

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

Related

MySql query to get Woo variable products with other product info on same line

Trying to get the ID, name and SKU of products for each variable product that have a custom meta field with another product ID in WooCommerce in the same result row via only one MySql query.
This is the query I made:
SELECT wp_posts.id, wp_posts.post_title, wp_postmeta.meta_value AS dms3sku FROM wp_posts, wp_postmeta WHERE wp_posts.post_type = "product_variation" AND wp_posts.id = wp_postmeta.post_id AND wp_postmeta.meta_key = "dms3sku"
sql result
This returns me the ID, name, and a custom meta field of the variable product called dms3sku that is the ID of another product. So have to find the ID, name and SKU of the product with the ID I got on the previous query called dms3sku and I need it in the same query I did.
need a result like that
Haven't found anything on internet and my Sql knowladge is not enough to solve that.

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

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.

Using AND between CASE statements in the WHERE clause SQL query

I have written a query which is as follows -
SELECT user_id, display_name, user_email, meta_key, meta_value
FROM wp_usermeta um INNER JOIN wp_users u ON um.user_id = u.id
WHERE
CASE
WHEN meta_key = "renewal_date" THEN meta_value = "a"
WHEN meta_key = "wp_user_level" THEN meta_value <> "10"
END
I need the user_id of the two 'when' statements to be equal. By that I mean, if the same user(having the same user_id) has meta_key as renewal_date and corresponding meta_value as a, and the same user has meta_key as wp_user _level and has the corresponding meta_value as 10 then he should not show in the result list. With my limited knowledge of SQL I was considering using AND between the WHEN statements but it gives me a syntactic error.
From your description I think I see what you are trying to do, but your query won't work like that. It looks like you have several rows per user id in the wp_usermeta table. This is known as an EAV model (entity-attribute-value) and that model makes reporting quite difficult, because you have rows that should be columns.
One way of getting it working is to join the wp_usermeta table multiple times (so rows become columns essentially), like this:
SELECT u.id, u.display_name, u.user_email,
rd.meta_value AS renewal_date, ul.meta_value AS wp_user_level
FROM wp_users u
LEFT JOIN wp_usermeta rd ON rd.user_id=u.id AND rd.meta_key='renewal_date'
LEFT JOIN wp_usermeta ul ON ul.user_id=u.id AND ul.meta_key='wp_user_level'
WHERE rd.meta_value = 'a'
AND ul.meta_value <> '10'
Please note that users who have no 'wp_user_level' data will be included in this report. If you need to filter those ones out you can replace LEFT JOIN with INNER JOIN.

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.

Wordpress/MySql query is not producing all results from the LEFT part of the JOIN

I am working in a MySQL database.
I have added a custom field to a Wordpress database called "short_url"
I want a list of all posts in the database along with the value for "short_url" if the post has that value. But I want all of the posts nonetheless. I have composed the following query and used a LEFT join so that I get back all posts even if there is no corresponding custom value, but it is not working.
SELECT
wp_posts.post_title
, wp_posts.post_date
, wp_postmeta.meta_value
FROM
wp_posts
LEFT JOIN wp_postmeta
ON ( wp_posts.ID = wp_postmeta.post_id)
WHERE (wp_postmeta.meta_key ="short url");
This query returns 12 results, which is how many articles have the custom value, but there are 193 posts in my database.
Why I am getting back is a list of only posts that have the "short_url" value?
How can I get a full list?
You need to move the condition from the WHERE clause to the ON clause. Conditions in a WHERE clause affect all of the results. Conditions in the ON clause affect the JOIN.
SELECT
wp_posts.post_title,
wp_posts.post_date,
wp_postmeta.meta_value
FROM
wp_posts
LEFT JOIN wp_postmeta
ON (wp_posts.ID = wp_postmeta.post_id) AND
(wp_postmeta.meta_key ="short url");