【问题标题】:Advanced Wordpress MySQL Query selecting products and attributes高级 Wordpress MySQL 查询选择产品和属性
【发布时间】:2013-09-22 17:46:03
【问题描述】:

过去 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

当您删除此块时,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 

我想展示几个属性:item-number、pa、da、mozrank、反向链接、referring-domains、tf、cf。

非常感谢您的帮助:)

编辑:表结构

wp_terms

  • term_id
  • 姓名

wp_term_taxonomy

  • term_taxonomy_id
  • term_id
  • 分类法

wp_term_relationships

  • object_id
  • term_taxonomy_id

wp_postmeta

  • post_id
  • meta_id
  • 元密钥
  • 元值

【问题讨论】:

  • 可以分享一下表结构吗?
  • 针对表结构进行了编辑。我希望这会有所帮助!

标签: mysql sql wordpress woocommerce


【解决方案1】:

我建议您将INNER JOINs 更改为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)

编辑

GROUP BY 子句有什么用途?您正在对GROUP BY 使用一个令人困惑的非标准 MySQL 扩展。阅读并理解它,或者摆脱GROUP BYhttp://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html 说真的。

您的查询中似乎发生了三件事。如果我们有机会解决这个问题,我们需要仔细分解这些东西。让我们使用 Structured Query Language 中的 Structured 来使其正常工作。

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

SELECT p.id, p.post_title, p.guid
  FROM wp_posts p 
  WHERE p.post_status = 'publish' 
    AND post_type = 'product' 

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

其次,您正在尝试检索和显示产品帖子的分类信息(类别、关键字等)。这是一个获取这些东西的查询,我认为(我不像你那样理解你的应用程序的这一部分)。我认为您正试图从两个分类领域中剔除。这是典型的 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 

测试这个查询。它应该为在“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 

第三,您正在从post_meta 检索特定属性。对于帖子和价格,以及帖子和库存状态,我们需要类似的东西。同样,编写这些查询并单独调试它们。这是价格。

  SELECT post_id AS id, meta_value AS price
    FROM wp_postmeta
   WHERE meta_key = `_regular_price'

这里是库存状态。

  SELECT post_id AS id, meta_value AS stockstatus
    FROM wp_postmeta
   WHERE meta_key = `_stock_status'

很好:我们有五个已调试的子查询。每个都在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'

我们在这里使用 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'

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

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

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

【讨论】:

  • 您好,感谢您的建议!您建议我将哪些 JOIN 更改为 LEFT JOIN?
  • 我试过这个,它似乎只适用于一个属性。当我添加多个时,它不会返回任何结果。
  • 查看我的详细编辑,了解如何逐步解决此问题。
  • 哇,非常感谢。我将把它拆开:) 我已经做 php/mysql 很长时间了,但在 baha 之前从来没有创建过这么大的单个查询。
【解决方案2】:

你有太多的加入它会增加你的加载时间..请像我一样做..

SELECT 
                p1.ID as id,
                p1.post_title as title,
                p1.post_content as description,
                p1.guid as link,
                (CASE WHEN pm1.meta_key = '_thumbnail_id' then p2.guid ELSE NULL END) as image_​​link,
                (CASE WHEN pm1.meta_key = '_stock_status' then pm1.meta_value ELSE NULL END) as availability,
                (CASE WHEN pm1.meta_key = '_sale_price' then pm1.meta_value ELSE NULL END) as sales_price,
                (CASE WHEN pm1.meta_key = '_price' then pm1.meta_value ELSE NULL END) as price,
                (CASE WHEN pm1.meta_key = '_regular_price' then pm1.meta_value ELSE NULL END) as regular_price
            FROM
                wp_posts p1
            LEFT JOIN
                wp_postmeta pm1
                ON (
                    pm1.post_id = p1.ID               
                ) 
            LEFT JOIN 
                wp_posts p2
                ON (
                    pm1.post_id = p2.ID 
                )
            WHERE 
                p1.post_type IN ('product','product_variation')
            AND
                p1.post_status = 'publish'
            GROUP BY p1.ID

【讨论】:

    猜你喜欢
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 2011-09-22
    • 1970-01-01
    相关资源
    最近更新 更多