我建议你把你INNER JOIN
的 s改成LEFT JOIN
s。 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
该条款的目的是什么?您正在使用一个邪恶的、令人困惑的非标准 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'
此查询是否产生适当的项目列表?它可能包含一些未定价的物品或其他类似的东西,但它至少应该包含清单中您需要的所有物品。
其次,您正在尝试检索和显示产品帖子的分类信息(类别、关键字等)。这是一个获取这些东西的查询,我认为(我不像你那样理解你的应用程序的这一部分)。我认为您正试图从两个分类领域中剔除。这是典型的 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
.
- 已发布产品帖子列表
- 所有帖子及其 pa_mozrank 分类的列表。
- 所有帖子及其 pa_pa 分类的列表。
- 价格。
- 备货状态。
现在我们需要将所有这些东西结合在一起。这是我们最终查询的概要。大概您可以看到这与您的原始查询有何关系。
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'
这是一个很长的查询,但是您可以很容易地看到它是如何组合在一起的,并且您可以逐个调试各个部分。
查询优化器旨在使这些东西尽可能高效,因此您不必担心这一点,除非您有数百万件待售商品,在这种情况下您可能是 amazon.com .
如果您是为一家大公司做这件事的企业开发人员,您可能会为子查询使用 SQL 视图。(如果您使用的是 Oracle 或 PostgreSQL,则可以WITH
在查询中使用子句。)您甚至可以在 WordPress 中执行此操作,但您可能希望编写一个插件,在激活和停用时创建和删除它们。仅使用大型 SQL 查询可能会更容易。