高级 WordPress MySQL 查询选择产品和属性

Bra*_*son 1 mysql sql wordpress woocommerce

过去 6 个小时我一直在处理这个问题,所以我想我应该在这里寻求帮助。

我的目标是在网站的页面上显示数据库中的所有产品。产品是域名,每一个产品都有需要展示的属性。

我很困惑,这是我到目前为止所得到的:

SELECT p.id, p.post_title, p.guid, 
       meta_price.meta_value as price, 
       mozrank.name as mozrank, 
       pa.name as pa 
  FROM wp_posts p 
 INNER JOIN wp_postmeta meta_price ON p.id=meta_price.post_id 
            AND meta_price.meta_key='_regular_price' 
 INNER JOIN wp_postmeta meta_instock ON p.id=meta_instock.post_id 
            AND meta_instock.meta_key='_stock_status' 
 INNER JOIN wp_term_relationships relationships ON p.id=relationships.object_id 
 INNER JOIN wp_term_taxonomy ttmozrank ON ttmozrank.taxonomy='pa_mozrank' 
            AND ttmozrank.term_taxonomy_id=relationships.term_taxonomy_id 
 INNER JOIN wp_terms mozrank ON mozrank.term_id=ttmozrank.term_id 
 INNER JOIN wp_term_taxonomy ttpa ON ttpa.taxonomy='pa_pa' 
            AND ttpa.term_taxonomy_id=relationships.term_taxonomy_id 
 INNER JOIN wp_terms pa ON pa.term_id=ttpa.term_id 
  WHERE p.post_status = 'publish' 
    AND post_type = 'product' 
    AND meta_price.meta_value<>''
    AND meta_instock.meta_value = 'instock'
  GROUP BY p.id
Run Code Online (Sandbox Code Playgroud)

当您删除此块时,MySQL 会输出我想要的内容,但仅针对一个属性。

        INNER JOIN wp_term_taxonomy ttpa ON ttpa.taxonomy='pa_pa' 
            AND ttpa.term_taxonomy_id=relationships.term_taxonomy_id 
        INNER JOIN wp_terms pa ON pa.term_id=ttpa.term_id 
Run Code Online (Sandbox Code Playgroud)

我想显示一些属性:item-number、pa、da、mozrank、反向链接、引用域、tf、cf。

非常感谢您的帮助:)

编辑:表结构

wp_术语

  • 术语 ID
  • 姓名

wp_term_taxonomy

  • term_taxonomy_id
  • 术语 ID
  • 分类

wp_term_关系

  • 对象 ID
  • term_taxonomy_id

wp_postmeta

  • 帖子编号
  • 元ID
  • 元键
  • 元值

O. *_*nes 5

我建议你INNER JOIN把s改成LEFT JOINs。 INNER JOIN如果连接左侧的表中没有任何匹配项,则将删除行。

您可能还想用ON括号重新编写子句,如下所示:

 INNER JOIN wp_term_taxonomy ttpa 
     ON (    ttpa.taxonomy='pa_pa' 
         AND ttpa.term_taxonomy_id=relationships.term_taxonomy_id)
Run Code Online (Sandbox Code Playgroud)

编辑

该条款的目的是什么GROUP BY?您正在使用一个邪恶且令人困惑的非标准 MySQL 扩展GROUP BY。阅读本文并理解它,或者摆脱GROUP BY. http://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html 说真的。

您的查询中似乎发生了三件事。如果我们想要解决这个问题,我们就需要仔细地分解这些东西。让我们使用结构化查询语言中的结构化来使其正常工作。

首先,您尝试获取包含特定帖子(在您的情况下为待售商品)的结果集。

SELECT p.id, p.post_title, p.guid
  FROM wp_posts p 
  WHERE p.post_status = 'publish' 
    AND post_type = 'product' 
Run Code Online (Sandbox Code Playgroud)

此查询是否会生成适当的项目列表?它可能包含一些未定价的物品或其他此类物品,但它至少应该包含您列表中所需的所有物品。

其次,您尝试检索并显示产品帖子的分类信息(类别、关键字等)。我认为这是一个获取这些东西的查询(我不像你一样理解你的应用程序的这一部分)。我认为您试图排除两个分类领域。这是典型的 WordPress 分类查找毛团。其中之一是这样的:

    SELECT tr.object_id AS id, 
           t.name       AS mozrank
      FROM wp_term_relationships AS tr  
INNER JOIN wp_term_taxonomy AS x 
             ON (x.taxonomy='pa_mozrank' 
            AND x.term_taxonomy_id=tr.term_taxonomy_id)
INNER JOIN wp_terms AS t 
             ON t.term_id=x.term_id 
Run Code Online (Sandbox Code Playgroud)

测试这个查询。它应该为“pa_mozrank”分类法中分类的每个帖子提供一行,显示该分类法中的帖子 ID 和 mozrank 值。确保此查询有效。如果没有,请弄清楚。在您理解这一点并使其发挥作用之前,请不要继续。

从 pa_pa 层次结构中获取值的查询也是如此。

    SELECT tr.object_id AS id, 
           t.name       AS pa
      FROM wp_term_relationships AS tr  
INNER JOIN wp_term_taxonomy AS x 
             ON (x.taxonomy='pa_pa' 
            AND x.term_taxonomy_id=tr.term_taxonomy_id)
INNER JOIN wp_terms AS t 
             ON t.term_id=x.term_id 
Run Code Online (Sandbox Code Playgroud)

第三,您从 中检索特定属性post_meta。我们需要类似的帖子和价格、帖子和库存状态。再次编写这些查询并单独调试它们。这里是价格。

  SELECT post_id AS id, meta_value AS price
    FROM wp_postmeta
   WHERE meta_key = `_regular_price'
Run Code Online (Sandbox Code Playgroud)

这是库存状态。

  SELECT post_id AS id, meta_value AS stockstatus
    FROM wp_postmeta
   WHERE meta_key = `_stock_status'
Run Code Online (Sandbox Code Playgroud)

好:我们有五个已调试的子查询。每个索引都在 上id

  1. 已发布的产品帖子列表
  2. 所有帖子及其 pa_mozrank 分类的列表。
  3. 所有帖子及其 pa_pa 分类的列表。
  4. 价格。
  5. 库存状态。

现在我们需要将所有这些东西结合在一起。这是我们最终查询的总体轮廓。想必您可以看到这与您的原始查询有何关系。

   SELECT whatever
     FROM wp_posts      AS p
LEFT JOIN (mozranks)    AS mo ON p.id = mo.id
LEFT JOIN (pas)         AS pa ON p.id = pa.id
LEFT JOIN (prices)      AS pr ON p.id = pr.id
LEFT JOIN (stockstatus) AS ss ON p.id = ss.id
    WHERE p.post_status = 'publish' 
      AND p.post_type = 'product' 
      AND pr.price <> ''
      AND ss.stockstatus = 'instock'
Run Code Online (Sandbox Code Playgroud)

我们在这里使用 LEFT JOIN 是因为我们仍然需要 wp_posts 表中的内容,即使它缺少部分或全部属性。

最后,把它们放在一起,我们得到了一个相当大的查询。但是我们得到一个查询,其中所有部分都经过了单元测试。所以,我们不必拍着额头说“WTF”?搞什么?在创建查询的这个阶段。

   SELECT whatever
     FROM wp_posts      AS p
LEFT JOIN (
            SELECT tr.object_id AS id, 
                   t.name       AS mozrank
              FROM wp_term_relationships AS tr  
        INNER JOIN wp_term_taxonomy AS x 
                     ON (x.taxonomy='pa_mozrank' 
                    AND x.term_taxonomy_id=tr.term_taxonomy_id)
        INNER JOIN wp_terms AS t 
                     ON t.term_id=x.term_id    
          ) AS mo ON p.id = mo.id
LEFT JOIN (
            SELECT tr.object_id AS id, 
                   t.name       AS pa
              FROM wp_term_relationships AS tr  
        INNER JOIN wp_term_taxonomy AS x 
                     ON (x.taxonomy='pa_pa' 
                    AND x.term_taxonomy_id=tr.term_taxonomy_id)
        INNER JOIN wp_terms AS t 
                     ON t.term_id=x.term_id 
          ) AS pa ON p.id = pa.id
LEFT JOIN (
           SELECT post_id AS id, meta_value AS price
             FROM wp_postmeta
            WHERE meta_key = `_regular_price'
          ) AS pr ON p.id = pr.id
LEFT JOIN (
           SELECT post_id AS id, meta_value AS stockstatus
             FROM wp_postmeta
            WHERE meta_key = `_stock_status'
          ) AS ss ON p.id = ss.id
    WHERE p.post_status = 'publish' 
      AND p.post_type = 'product' 
      AND pr.price <> ''
      AND ss.stockstatus = 'instock'
Run Code Online (Sandbox Code Playgroud)

这是一个很长的查询,但您可以很容易地看到它是如何组合在一起的,并且可以逐个调试各个部分。

查询优化器旨在使这些东西尽可能高效,因此您不必担心这一点,除非您有数百万件待售商品,在这种情况下您可能是 amazon.com 无论如何。

如果您是为一家大公司执行此操作的企业开发人员,您可能会使用 SQL 视图进行子查询。(如果您使用的是 Oracle 或 PostgreSQL,则可以WITH在查询中使用子句。)您甚至可以在 WordPress 中执行此操作,但您可能希望编写一个插件来在激活和停用时创建和删除它们。仅使用大型 SQL 查询可能会更容易。