Как я могу объединить одно поле, используя wpdb и сгруппировать по?

Вопрос или проблема

У меня есть следующий код в моем файле functions.php, где я пытаюсь сгруппировать количество проданных товаров из заказов WooCommerce по выбранной вариации товара. Мой запрос:

$uvuorderposts = $wpdb->get_results( 
    "
    SELECT p.ID, p.post_title, p.post_date, wcom.order_item_name, wcomm.meta_key, wcomm.meta_value, wcomm2.meta_key AS meta_key_qty, wcomm2.meta_value AS meta_value_qty, pm2.meta_value AS meta_value_location
    FROM $wpdb->posts AS p
    INNER JOIN $wpdb->postmeta AS pm ON p.ID = pm.post_id
    INNER JOIN $wpdb->woocommerce_order_items AS wcom ON p.ID = wcom.order_id
    INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm ON wcom.order_item_id = wcomm.order_item_id
    INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm2 ON wcom.order_item_id = wcomm2.order_item_id
    INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm3 ON wcom.order_item_id = wcomm3.order_item_id
    INNER JOIN $wpdb->postmeta AS pm2 ON pm2.post_id = wcomm3.meta_value
    WHERE (p.post_type="shop_order")
    AND (pm.meta_key = '_wc_authorize_net_aim_charge_captured')
    AND (pm.meta_value="yes")
    AND (wcomm.meta_key = '_product_id')
    AND (wcomm.meta_value="4034")
    AND (wcomm2.meta_key = '_qty')
    AND (wcomm3.meta_key = '_variation_id')
    AND (pm2.meta_key = 'attribute_pa_seminar-location')
    ORDER BY p.post_date
    "
);

echo "<table>";
foreach ( $uvuorderposts as $uvuorderpost ) 
{
    echo "<tr bgcolor="#eaeaea"><td colspan='2'>" . $uvuorderpost->meta_key_qty . " : " .  $uvuorderpost->meta_value_qty . "</td></tr>";
    echo "<tr bgcolor="#eaeaea"><td colspan='2'>" . strtoupper($uvuorderpost->meta_value_location) . "</td></tr>";      
}
echo "</table>";

Вывод дает мне:

_qty : 1
WY
_qty : 1
WV
_qty : 1
GA
_qty : 1
GA

Мне нужно, чтобы он был таким:

_qty : 1
WY
_qty : 1
WV
_qty : 2
GA

Я добавил GROUP BY pm2.meta_value, и это убрало вторую строку с GA, но не объединило значение _qty. Пожалуйста, помогите, как объединить значение _qty между возвращенными записями?

Заработало, когда добавил

$uvusql = $wpdb->prepare( 
    "
    SELECT p.ID, p.post_title, p.post_date, wcom.order_item_name, wcomm.meta_key, wcomm.meta_value, wcomm2.meta_key AS meta_key_qty, wcomm2.meta_value AS meta_value_qty, pm2.meta_value AS meta_value_location
    FROM $wpdb->posts AS p
    INNER JOIN $wpdb->postmeta AS pm ON p.ID = pm.post_id
    INNER JOIN $wpdb->woocommerce_order_items AS wcom ON p.ID = wcom.order_id
    INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm ON wcom.order_item_id = wcomm.order_item_id
    INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm2 ON wcom.order_item_id = wcomm2.order_item_id
    INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm3 ON wcom.order_item_id = wcomm3.order_item_id
    INNER JOIN $wpdb->postmeta AS pm2 ON pm2.post_id = wcomm3.meta_value
    WHERE (p.post_type="shop_order")
    AND (pm.meta_key = '_wc_authorize_net_aim_charge_captured')
    AND (pm.meta_value="yes")
    AND (wcomm.meta_key = '_product_id')
    AND (wcomm.meta_value="4034")
    AND (wcomm2.meta_key = '_qty')
    AND (wcomm3.meta_key = '_variation_id')
    AND (pm2.meta_key = 'attribute_pa_seminar-location')
    ORDER BY p.post_date
    "
);

$uvuorderposts = $wpdb->get_results( $uvusql, ARRAY_A );

 $uvugroups = array();
    $uvukey = "";
    $uvukeyc = 0;
    foreach ($uvuorderposts as $item) {
        $uvukey = $item['meta_value_location'];
        if (!array_key_exists($uvukey, $uvugroups)) {
            $uvugroups[$uvukey] = array(
                'id' => $item['meta_value_location'],
                'qty' => $item['meta_value_qty'],
            );
        } else {
            $uvugroups[$uvukey]['qty'] = $uvugroups[$uvukey]['qty'] + $item['meta_value_qty'];
        }
        $uvukeyc++;                       
    }

    print "<pre>";
    print_r($uvugroups);
    print "</pre>";

Ответ или решение

Конечно, давайте разберемся с этой задачей на уровне эксперта. Основной целью является объединение количества продаж (qty) на основе конкретного атрибута, такого как местоположение. В данном случае проблема заключается в том, что вы хотите суммировать количества для каждой уникальной пары "местоположение-артикул" и отобразить их в результирующем наборе данных.

Шаг 1: Оптимизация SQL-запроса

Для решения задачи необходимо изменить SQL-запрос так, чтобы выполнять группировку записей. В SQL для этого используются агрегатные функции, такие как SUM(), которые помогут посчитать общее количество товаров для каждой группы. В запрос необходимо добавить следующие изменения:

SELECT 
    pm2.meta_value AS meta_value_location,
    SUM(CAST(wcomm2.meta_value AS UNSIGNED)) AS total_qty
FROM $wpdb->posts AS p
INNER JOIN $wpdb->postmeta AS pm ON p.ID = pm.post_id
INNER JOIN $wpdb->woocommerce_order_items AS wcom ON p.ID = wcom.order_id
INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm ON wcom.order_item_id = wcomm.order_item_id
INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm2 ON wcom.order_item_id = wcomm2.order_item_id
INNER JOIN $wpdb->woocommerce_order_itemmeta AS wcomm3 ON wcom.order_item_id = wcomm3.order_item_id
INNER JOIN $wpdb->postmeta AS pm2 ON pm2.post_id = wcomm3.meta_value
WHERE 
    p.post_type = "shop_order" AND
    pm.meta_key = '_wc_authorize_net_aim_charge_captured' AND
    pm.meta_value = "yes" AND
    wcomm.meta_key = '_product_id' AND
    wcomm.meta_value = "4034" AND
    wcomm2.meta_key = '_qty' AND
    wcomm3.meta_key = '_variation_id' AND
    pm2.meta_key = 'attribute_pa_seminar-location'
GROUP BY pm2.meta_value
ORDER BY p.post_date

Шаг 2: Обработка результатов

После выполнения корректного SQL-запроса, данные необходимо собрать в виде массивов для дальнейшей работы с результатами.

$uvuorderposts = $wpdb->get_results($uvusql, ARRAY_A);

$uvugroups = [];
foreach ($uvuorderposts as $item) {
    $uvugroups[] = [
        'location' => strtoupper($item['meta_value_location']),
        'qty' => $item['total_qty']
    ];
}

echo "<table>";
foreach ($uvugroups as $group) {
    echo "<tr bgcolor=\"#eaeaea\"><td>" . $group['qty'] . "</td><td>" . $group['location'] . "</td></tr>";
}
echo "</table>";

Заключение

Данный подход позволяет получить корректные результаты агрегирования количества товаров по местоположению. Он также обеспечивает оптимизацию выполнения запросов и обработку данных. Убедитесь, что код соответствует всем стандартам безопасности и совместим с установленными версиями WooCommerce и WordPress. Надеюсь, это решение поможет вам успешно справиться с поставленной задачей.

Оцените материал
Добавить комментарий

Капча загружается...