【问题标题】:Woocommerce SQL query to show products sold this week?Woocommerce SQL 查询显示本周售出的产品?
【发布时间】:2014-03-06 17:14:37
【问题描述】:

Woocommerce 有一个报告工具,可以显示过去 7 天最畅销的产品。但它只显示排名前 12 位的产品。

我想创建一个 SQL 查询,它会显示过去 7 天销售的所有产品,而不仅仅是前 12 天。

以前有人做过吗?

【问题讨论】:

  • 提供你的表结构。

标签: mysql sql wordpress woocommerce


【解决方案1】:

WooCommerce 大量借鉴了 WordPress 本身存储数据的方式:帖子用作基本数据对象,其中包含所有自定义帖子共有的少数列。任何特定于自定义类型的唯一数据都作为键值对存储在 post_meta 中。这意味着没有干净的列或表来查询订单行项目、sku、行项目价格等内容。

值得一提的是,对于订单,WC 不存储产品,它存储订单项。这是因为您可以将费用、通用订单项和可能的其他东西添加到不是产品的订单中。此外,WC 需要存储订单时的价格,因为客户可能有折扣或产品价格可能已更改。

WooCommerce 使用 WordPress postmeta 表和它自己的 order_itemmeta 表。以下是它的分解方式:

  • 订单本身在wp_posts 表中存储为“shop_order”的自定义帖子类型
  • 订单行项目存储在名为wp_woocommerce_order_items 的关系表中
  • 订单商品详情作为键值对存储在wp_woocommerce_order_itemmeta
  • 最终订单详情存储在wp_postmeta 表中

因此,假设您想查看一段时间内的所有订单项,并且您想知道项目标题、价格以及它所属的订单等信息。为此,您必须加入多个表,并为您想要的特定字段加入或子查询元表。在下面的示例中,我使用了子查询,因为我认为它们更具可读性,请注意 JOIN 很可能更快。

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"

如您所见,每个 行项目字段需要一个子查询/连接,您希望这些查询非常昂贵。我怀疑 WC 会因此限制查询报告的数量。

此答案已针对 WC 版本 3.3.4 进行了测试。

【讨论】:

  • 我刚刚意识到我在其中留下了帖子表的第二个连接,别名为“产品”的“p”。但我实际上并没有选择任何字段。如果订单项是产品,则该联接用于获取产品数据。您可以扩展您的选择以包含来自该联接的更多产品数据。
【解决方案2】:

无需编写新查询,只需使用过滤器修改现有查询:

woocommerce_reports_get_order_report_query

似乎报告页面的所有部分的限制都是相同的,因此更改此限制将影响所有带有限制子句的查询。我不会过多考虑产品的数量,因为对于列出的每个产品都会执行一个新的 sql 查询。

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;  
});

【讨论】:

    【解决方案3】:

    只是猜测

    ....WHERE dateColumn BETWEEN DATE_SUB(NOW(),INTERVAL 1 WEEK) AND NOW()
    

    添加更多信息,以获得更准确的答案。

    【讨论】:

    • 你怎么知道这是问题的答案?如果您需要更多信息,请询问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    相关资源
    最近更新 更多