Get all WooCommerce customers paid orders with a SQL query - php

I need a query that returns me all the users with orders with payment approved.
I'm having a hard time finding where in the db this is stored. I found only post_status 'wc-complete', but I don't think this is the right info.
SELECT a.post_status, b.meta_value FROM wp_posts a, wp_postmeta b
WHERE a.ID = b.post_id
AND a.post_type = 'shop_order'
AND a.post_status = 'wc-completed'

Using "completed" order status for paid orders is correct
Here is a custom function with a SQL query, that will output an formatted array of User IDs with their completed orders (paid / accepted):
function completed_orders_ids_by_costumer_id(){
global $wpdb;
$query = $wpdb->get_results("
SELECT pm.meta_value AS user_id, pm.post_id AS order_id
FROM {$wpdb->prefix}postmeta AS pm
LEFT JOIN {$wpdb->prefix}posts AS p
ON pm.post_id = p.ID
WHERE p.post_type = 'shop_order'
AND p.post_status = 'wc-completed'
AND pm.meta_key = '_customer_user'
ORDER BY pm.meta_value ASC, pm.post_id DESC
");
// We format the array by user ID
foreach($query as $result)
$results[$result->user_id][] = $result->order_id;
return $results;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works.
EXAMPLE USAGE just for test to see the raw outputted data
echo '<pre>'; print_r(completed_orders_ids_by_costumer_id()); echo '</pre>';
You will get something like:
Array
(
[9] => Array
(
[0] => 505
[0] => 497
)
[12] => Array
(
[0] => 626
[1] => 584
[2] => 483
)
[15] => Array
(
[0] => 614
[1] => 598
)
[17] => Array
(
[0] => 634
)
… / … and so on …
)
Now in wp_postmeta table you will also some other meta keys related to paid orders that you could use:
• '_paid_date'
• '_date_paid'
• '_date_completed'
• '_completed_date'
But targeting "completed" order status is just fine
Using that others listed meta keys, you can make your SQL query (that can replace our first query in the function):
$query = $wpdb->get_results("
SELECT DISTINCT pm.meta_value AS user_id, pm.post_id AS order_id
FROM {$wpdb->prefix}postmeta AS pm
LEFT JOIN {$wpdb->prefix}posts AS p
ON pm.post_id = p.ID
LEFT JOIN {$wpdb->prefix}postmeta AS pm2
ON p.ID = pm2.post_id
WHERE p.post_type = 'shop_order'
AND pm.meta_key = '_customer_user'
AND pm2.meta_key IN ( '_paid_date', '_paid_date', '_date_completed', '_completed_date' )
AND pm2.meta_value != ''
ORDER BY pm.meta_value ASC, pm.post_id DESC
");
Tested and works too…

Related

MySql query result to have nested arrays

I just want my query to return a result looking like this:
array(
[k1] => data1
[k2] => data2
[items] => array(
[item1] => array(
.... data inside
)
[item2] => array(
.... data inside
)
)
)
Here is my query:
SELECT o.*
, ot.tracking_number
, p.id payId
, p.customer_id payCustId
, p.name payName
, p.status payStatus
, p.charge payTotalCharge
, op.*
FROM orders o
JOIN payments o
ON p.id = o.payment_id
LEFT
JOIN orders_tracking ot
ON ot.order_id = o.id
JOIN orderdetails od
ON od.order_id = o.id
JOIN orderproducts op
ON op.orderdetail_id = od.id
WHERE p.customer_id = $customer_id;
What is wrong with my query that it won't return the way I wanted it to?
Thanks.

Foreach not displaying the Results

Hi am using the following Query need to get the order_id and product_id from this query ,
well when I run the query in phpmyadmin results are displayed.
global $wpdb;
$sql = "SELECT oi.order_id, p.ID as product_id, p.post_title, p.post_author as seller_id,
oim2.meta_value as order_total, terms.name as order_status
FROM {$wpdb->prefix}woocommerce_order_items oi
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oim.order_item_id = oi.order_item_id
LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim2 ON oim2.order_item_id = oi.order_item_id
LEFT JOIN $wpdb->posts p ON oim.meta_value = p.ID
LEFT JOIN {$wpdb->term_relationships} rel ON oi.order_id = rel.object_id
LEFT JOIN {$wpdb->term_taxonomy} tax ON rel.term_taxonomy_id = tax.term_taxonomy_id
LEFT JOIN {$wpdb->terms} terms ON tax.term_id = terms.term_id
WHERE
oim.meta_key = '_product_id' AND
oim2.meta_key = '_line_total'
GROUP BY oi.order_id";
$orders = $wpdb->get_results( $sql );
if ( $orders ) {
foreach ($orders as $order) {
$result=customFunction(**$order->order_id,$order->product_id,$order->seller_id**);
}
the problem is $order->order_id and $order->product_id value is not getting passed to the function but only $order->seller_id is getting passed. But in phpmyadmin the values are present for all the three variables.
tried
echo $orders[product_id] ;
echo $orders[order_id] ;
echo $orders[seller_id];
Hut only echo $orders[seller_id]; shows the value.
Here is the array structure:
Array (
[0] => stdClass Object (
[order_id] => 2774
[product_id] => 2531
[post_title] => Klassic Koalas Mug
[seller_id] => 3
[order_total] => 12
[order_status] => cancelled
)
[1] => stdClass Object (
[order_id] => 2869
[product_id] => 2622
[post_title] => Mug, Aqua
[seller_id] => 1
[order_total] => 1
[order_status] => on-hold
)
I'll put this in a comment but I don't have enough reputation. Do:
var_dump($orders)
and see what's inside. Maybe they are fetched as 'oi.order_id'.
Unsure about product_id, but it seems that order_id is not showing up because you are not setting and alias for order_id. So take this:
SELECT oi.order_id,
And change it to this
SELECT oi.order_id as order_id,
Past that do a dump of $orders to see the overall structure like this:
echo '<pre>';
print_r($orders);
echo '</pre>';
Lets debug this first, var_dump is your friend! try :
$orders = $wpdb->get_results( $sql );
var_dump($orders); die();
Now, after adding the var_dump, check the result, if order_id and product_id still don't have result, might be there is a DB issue? Then you have to fix your DB first.

get all tags with sql query

I have this sql that is made by help of others.
$sql ="
select e.*, i.*, group_concat( t.tag separator ',') as tag_list
from nv_entries e
JOIN nv_tags t on t.entrie_id = e.id
LEFT JOIN nv_images i on i.entrie_id = e.id
where t.tag in ( $tag_list )
group by e.id
having count(t.id) = $num_tags ";
The result is this (i only show one entrie here, could be more):
[1] => Array
(
[id] => 2
[band] => Kids for Cash
[album] => No More Walls E.P.
[label] =>
[year] => 1986
[text] => Text about album kids for cash.
[entrie_id] => 2
[source] => img02_9lch1.png
[tag_list] => tree
)
For the tags, i have to show all tags that a entrie has and highlight the tags that where used to get the result. In this case [tag_list] => tree only shows one tag, the one that was used in the search field. My question is, how can i get a result like this?:
...
[tag_list] => tree, green, foo, bar
[used_tags] => tree
)
As a array is also good, but then please also an array when it's just one item.
If I understood correctly use >= in the having condition
$sql ="
select e.*, i.*, group_concat( t.tag separator ',') as tag_list
from nv_entries e
LEFT JOIN nv_images i on i.entrie_id = e.id
JOIN nv_tags t on t.entrie_id = e.id
where t.tag in ( $tag_list )
group by e.id
having count(t.id) >= $num_tags ";
ADD
subquery approach:
$sql ="
select e.*, i.*, group_concat( t.tag separator ',') as tag_list
from nv_entries e
JOIN nv_tags t on t.entrie_id in (
select se.id
from nv_entries se
JOIN nv_tags st on st.entrie_id = se.id
where st.tag in ( $tag_list )
group by se.id
having count(st.id) >= $num_tags
)
LEFT JOIN nv_images i on i.entrie_id = e.id
WHERE 1
group by e.id
";
Into subquery I get the ID list of entrie havin at least requested tags, then in main query I get all infox
ADD fixed query (see asker comment)
subquery approach, fix the lost join between "e" and "t" :
$sql ="
select e.*, i.*, group_concat( t.tag separator ',') as tag_list
from nv_entries e
JOIN nv_tags t on t.entrie_id = e.id
LEFT JOIN nv_images i on i.entrie_id = e.id
WHERE e.id in (
select se.id
from nv_entries se
JOIN nv_tags st on st.entrie_id = se.id
where st.tag in ( $tag_list )
group by se.id
having count(st.id) >= $num_tags
)
group by e.id
";

SQL & PHP query with union

I have this query string...
select i.invoiceid, i.date, i.total, i.total - (select ifnull(sum(p.amount), 0) from payment p where p.invoice = i.invoiceid) as remainingbalance
from invoice i inner join client c
on i.client = c.clientid
where i.isdeleted = 0 and i.client = 1
union
select p.paymentid, p.date, p.invoice, p.amount from payment p inner join invoice i
on i.invoiceid = p.invoice
inner join paymenttype
on paymenttype.paymenttypeid = p.paymenttypeid
inner join client c
on c.clientid = i.client
where c.clientid = 1
and i.isdeleted = 0
order by date
when I try this...
<?php
echo $clientArrayInvoice[1]['paymentid'];
?>
I get no results when I do a print_r on on $clientArrayInvoice I get this
Array ( [0] => Array ( [invoiceid] => 1 [date] => 2012-04-12 [total] => 602.29 [remainingbalance] => 300.96 ) [1] => Array ( [invoiceid] => 1 [date] => 2012-04-27 [total] => 1.00 [remainingbalance] => 301.33 ) )
I understand why its doing this, but how do I get the column to say paymentid instead of invoiceid for the results returned. so I can determine what is a paymentid and what is a invoiceid I hope this makes sense.
select i.invoiceid as transactionid, i.date, i.total,
i.total - (select ifnull(sum(p.amount), 0) from payment p where p.invoice = i.invoiceid) as remainingbalance,
'invoice' as transaction_type
from invoice i inner join client c
on i.client = c.clientid
where i.isdeleted = 0 and i.client = 1
union
select p.paymentid as transactionid, p.date, p.invoice, p.amount, 'payment' as transaction_type
from payment p inner join invoice i
on i.invoiceid = p.invoice
inner join paymenttype
on paymenttype.paymenttypeid = p.paymenttypeid
inner join client c
on c.clientid = i.client
where c.clientid = 1
and i.isdeleted = 0
order by date

return data from different table sql to html

My users have pages:
user favorites
users image
I try to do a page "everything" which will get data from 2 sql tables (already have sql code) to one html page ordering all by date. Problem is that "user image" have one html structure and "user favorites" another. Many website have such pages where is output different data in different html structure from different tables. Today I first time tried to do this and do not know the correct way.
My tables:
users
id
username
images
id
user_id
image
description
date <--- uplaod date
user_favorites
id
user_id <---user id who like image
image_id <---id of liked image
date <---date when image was clicked "liked"
I get user images with this sql
function users_pictures($user_id)
{
$sql = "SELECT username as user, p.image as user_image, i.image, i.id as image_id, i.description as text, UNIX_TIMESTAMP(i.date) as image_date, COALESCE ( imgcount.cnt, 0 ) as comments
FROM users u
LEFT JOIN images i ON i.user_id = u.id
LEFT JOIN images p ON p.id = (SELECT b.id FROM images AS b where u.id = b.user_id ORDER BY b.id DESC LIMIT 1)
LEFT JOIN (SELECT image_id, COUNT(*) as cnt FROM commentaries GROUP BY image_id ) imgcount ON i.id = imgcount.image_id
WHERE i.user_id = ?
ORDER BY i.date DESC";
$query = $this->db->query($sql, $user_id);
return $query->result_array();
}
I get all users image and user current image - avatar (last upload image is user avatar)
return example :
[images_list] => Array
(
[0] => Array
(
[user] => 8888
[user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[image] => http://127.0.0.1/auth_system_1/upload_images/224/224_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[image_id] => 4
[text] =>
[image_date] => 50 minutes
[comments] => 0
[user_first_image] => 1
)
)
User favorite table is :
function users_favorites_list($user_id)
{
$sql = "SELECT
u.username as user,
p.image as user_image,
fav.id as favorite_id,
UNIX_TIMESTAMP(fav.date) as favorite_date,
i.id as images_id,
i.image,
i.description as text,
u2.username as favorite_user,
t.image as favorite_user_image
FROM users u
LEFT JOIN user_favorites fav ON fav.user_id = u.id
LEFT JOIN user_follow f ON f.follow_id = fav.user_id
LEFT JOIN images i ON i.id = fav.image_id
LEFT JOIN users u2 ON u2.id = i.user_id
LEFT JOIN images p ON p.id = (SELECT b.id FROM images AS b where fav.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)
LEFT JOIN images t ON t.id = (SELECT b.id FROM images AS b where u2.id = b.user_id ORDER BY b.id DESC LIMIT 1)
WHERE fav.user_id = ?
GROUP BY fav.id
ORDER BY fav.date DESC";
$query = $this->db->query($sql, array($user_id, $user_id));
return $query->result_array();
}
return example:
Array
(
[0] => Array
(
[user] => 8888
[user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[favorite_id] => 5
[favorite_date] => 18 minutes ago
[images_id] => 2
[image] => http://127.0.0.1/auth_system_1/upload_images/100/100_flw3utn9igiqh7dtt2o61ydf8_174.jpeg
[text] => 3
[favorite_user] => 6666
[favorite_user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_flw3utn9igiqh7dtt2o61ydf8_174.jpeg
)
[1] => Array
(
[user] => 8888
[user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[favorite_id] => 2
[favorite_date] => 1 week ago
[images_id] => 4
[image] => http://127.0.0.1/auth_system_1/upload_images/100/100_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[text] =>
[favorite_user] => 8888
[favorite_user_image] => http://127.0.0.1/auth_system_1/upload_images/24/24_0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
)
)
:
![My html structure where I try to return data from 2 sql][1]
I need select user activities from 2 table in one page with different html structures (example see image) . I think many peole do it. Please tell me how to do this?
[everything_list] => Array
(
[0] => Array
(
[user] => 8888
[user_image] => 0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[favorite_id] => 5
[favorite_date] => 1328565406
[images_id] => 2
[image] => flw3utn9igiqh7dtt2o61ydf8_174.jpeg
[text] => 3
[favorite_user] => 6666
[favorite_user_image] => flw3utn9igiqh7dtt2o61ydf8_174.jpeg
)
[1] => Array
(
[user] => 8888
[user_image] => 0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[favorite_id] => 2
[favorite_date] => 1327856547
[images_id] => 4
[image] => 0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
[text] =>
[favorite_user] => 8888
[favorite_user_image] => 0j1kjjzdv3ez07a0ee4lnmjb7_163.jpeg
)
)
The query below return what you need?
SELECT
username as user,
p.image as user_image,
i.image,
i.id as image_id,
i.description as text,
UNIX_TIMESTAMP(i.date) as image_date,
COALESCE ( imgcount.cnt, 0 ) as comments,
fav.id as favorite_id,
UNIX_TIMESTAMP(fav.date) as favorite_date,
u2.username as favorite_user,
t.image as favorite_user_image
FROM users u
LEFT JOIN user_favorites fav ON fav.user_id = u.id
LEFT JOIN user_follow f ON f.follow_id = fav.user_id
LEFT JOIN images i ON i.user_id = u.id
LEFT JOIN users u2 ON u2.id = i.user_id
LEFT JOIN images p ON p.id = (SELECT b.id FROM images AS b where u.id = b.user_id ORDER BY b.id DESC LIMIT 1)
LEFT JOIN (SELECT image_id, COUNT(*) as cnt FROM commentaries GROUP BY image_id ) imgcount ON i.id = imgcount.image_id
LEFT JOIN images t ON t.id = (SELECT b.id FROM images AS b where u2.id = b.user_id ORDER BY b.id DESC LIMIT 1)
WHERE u.user_id = ?
GROUP BY fav.id
ORDER BY i.date DESC

Categories